diff --git a/assets/sai.js b/assets/sai.js
index 4ba1a1a..1907408 100644
--- a/assets/sai.js
+++ b/assets/sai.js
@@ -3328,6 +3328,15 @@ window.addEventListener("load", function() {
}
},
{
+ label: "Remove all tries",
+ callback: () => {
+ sai.send(JSON.stringify({
+ schema: "com.warmcat.sai.taskremovealltries",
+ uuid: taskUuid
+ }));
+ }
+ },
+ {
label: `Rebuild all <b>${hsanitize(platform)}</b>`,
callback: () => {
sai.send(JSON.stringify({
diff --git a/src/builder/b-nspawn.c b/src/builder/b-nspawn.c
index 881eb5c..33623cb 100644
--- a/src/builder/b-nspawn.c
+++ b/src/builder/b-nspawn.c
@@ -115,7 +115,18 @@ callback_sai_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
switch (reason) {
+#if defined(WIN32)
+ case LWS_CALLBACK_RAW_ADOPT_FILE:
+ lwsl_user("%s: wsi %p, reason %d, op %p, fd %d\n", __func__,
+ wsi, reason, op, lws_spawn_get_stdfd(wsi));
+ break;
+#endif
+
case LWS_CALLBACK_RAW_CLOSE_FILE:
+#if defined(WIN32)
+ lwsl_user("%s: wsi %p, CLOSE_FILE, op %p, fd %d\n", __func__,
+ wsi, op, lws_spawn_get_stdfd(wsi));
+#endif
{
int ch = lws_spawn_get_stdfd(wsi);
if (ch == 0) ch = 1;
@@ -138,9 +149,10 @@ callback_sai_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
{
DWORD rb;
if (!ReadFile((HANDLE)lws_get_socket_fd(wsi), buf, sizeof(buf) - 1, &rb, NULL)) {
- lwsl_debug("%s: read on stdwsi failed\n", __func__);
+ if (GetLastError() != 109 && GetLastError() != 232) lwsl_user("%s: read on stdwsi failed, err %lu\n", __func__, GetLastError());
return -1;
}
+ lwsl_user("%s: WIN32 RX_FILE read %lu bytes on fd %d\n", __func__, rb, lws_spawn_get_stdfd(wsi));
ilen = (int)rb;
}
#else
@@ -155,9 +167,9 @@ callback_sai_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
buf[len] = '\0';
if (!op || !op->ns || !op->ns->spm) {
- printf("%s: (%d) %s\n", __func__,
+ lwsl_notice("%s: (%d) [orphaned] %s\n", __func__,
(int)lws_spawn_get_stdfd(wsi), (const char *)buf);
- return -1;
+ return 0;
}
{
@@ -168,8 +180,10 @@ callback_sai_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
if (ch < 3)
op->ns->stdwsi[ch] = wsi;
- if (saib_log_chunk_create(op->ns, buf, len, ch))
+ if (saib_log_chunk_create(op->ns, buf, len, ch)) {
+ lwsl_user("%s: saib_log_chunk_create failed (ch %d, len %d)\n", __func__, ch, (int)len);
return -1;
+ }
if (lws_buflist2_total_len(&op->ns->spm->bl_to_srv) > (LWS_BUFLIST_OOM_LIMIT - (256 * 1024))) {
/* buflist is getting full, backpressure ALL active stdwsi for this connection */
@@ -644,7 +658,11 @@ saib_spawn_script(struct sai_nspawn *ns)
info.max_log_lines = 10000;
info.timeout_us = 30 * 60 * LWS_US_PER_SEC;
info.reap_cb = sai_lsp_reap_cb;
+#if defined(WIN32)
+ info.pty_mode = 0;
+#else
info.pty_mode = 1;
+#endif
info.disable_ctrlc = 1;
memset(&ns->res, 0, sizeof(ns->res));
info.res = &ns->res;
@@ -672,8 +690,10 @@ saib_spawn_script(struct sai_nspawn *ns)
info.owner = &builder.lsp_owner;
info.plsp = &op->lsp;
+ lwsl_user("%s: calling lws_spawn_piped for task uuid %s\n", __func__, ns->task->uuid);
lws_spawn_piped(&info);
if (!op->lsp) {
+ lwsl_user("%s: lws_spawn_piped failed to provide lsp\n", __func__);
/*
* op is attached to wsi and will be freed in reap cb,
* we can't free it here
@@ -682,6 +702,7 @@ saib_spawn_script(struct sai_nspawn *ns)
return 1;
}
+ lwsl_user("%s: lws_spawn_piped success, op->lsp %p\n", __func__, op->lsp);
return 0;
}
@@ -710,7 +731,19 @@ callback_sai_shell_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
int ilen;
switch (reason) {
+
+#if defined(WIN32)
+ case LWS_CALLBACK_RAW_ADOPT_FILE:
+ lwsl_user("%s: wsi %p, reason %d, sh %p, fd %d\n", __func__,
+ wsi, reason, sh, lws_spawn_get_stdfd(wsi));
+ break;
+#endif
+
case LWS_CALLBACK_RAW_CLOSE_FILE:
+#if defined(WIN32)
+ lwsl_user("%s: wsi %p, CLOSE_FILE, sh %p, fd %d\n", __func__,
+ wsi, sh, lws_spawn_get_stdfd(wsi));
+#endif
{
int ch = lws_spawn_get_stdfd(wsi);
if (ch == 0) ch = 1;
@@ -723,8 +756,11 @@ callback_sai_shell_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
#if defined(WIN32)
{
DWORD rb;
- if (!ReadFile((HANDLE)lws_get_socket_fd(wsi), buf, sizeof(buf) - 1, &rb, NULL))
+ if (!ReadFile((HANDLE)lws_get_socket_fd(wsi), buf, sizeof(buf) - 1, &rb, NULL)) {
+ lwsl_user("%s: read on shell stdwsi failed, err %lu\n", __func__, GetLastError());
return -1;
+ }
+ lwsl_user("%s: WIN32 RX_FILE read %lu bytes on shell fd %d\n", __func__, rb, lws_spawn_get_stdfd(wsi));
ilen = (int)rb;
}
#else
diff --git a/src/builder/b-power.c b/src/builder/b-power.c
index b8fc1b6..9c04813 100644
--- a/src/builder/b-power.c
+++ b/src/builder/b-power.c
@@ -468,7 +468,6 @@ sul_idle_cb(lws_sorted_usec_list_t *sul)
#endif
lws_ss_state_return_t r;
- char path[256];
#if !defined(WIN32)
if (builder.stay) {
@@ -538,12 +537,12 @@ sul_idle_cb(lws_sorted_usec_list_t *sul)
* request our suspender process to shutdown the device.
*/
- snprintf(path, sizeof(path) - 1, "%s/auto-power-off/%s",
+ snprintf(builder.path_power_off, sizeof(builder.path_power_off) - 1, "%s/auto-power-off/%s",
builder.url_sai_power, builder.host);
- lwsl_notice("%s: requesting sai-power (or virt) to terminate us: %s\n", __func__, path);
+ lwsl_notice("%s: requesting sai-power (or virt) to terminate us: %s\n", __func__, builder.path_power_off);
- r = lws_ss_set_metadata(builder.ss_power_off, "url", path, strlen(path));
+ r = lws_ss_set_metadata(builder.ss_power_off, "url", builder.path_power_off, strlen(builder.path_power_off));
if (r)
lwsl_err("%s: set_metadata said %d\n", __func__, (int)r);
diff --git a/src/builder/b-private.h b/src/builder/b-private.h
index 87a2591..39b9a58 100644
--- a/src/builder/b-private.h
+++ b/src/builder/b-private.h
@@ -158,6 +158,7 @@ struct sai_builder {
const char *rebuild_script_root;
char path[256];
+ char path_power_off[256];
#if defined(__linux__) || defined(__APPLE__)
/* For system-wide load calculation */
diff --git a/src/builder/b-task.c b/src/builder/b-task.c
index 5142dc9..08f945a 100644
--- a/src/builder/b-task.c
+++ b/src/builder/b-task.c
@@ -245,6 +245,11 @@ int
saib_set_ns_state(struct sai_nspawn *ns, int state)
{
struct sai_plat_server *spm = ns ? ns->spm : NULL;
+
+ if (ns)
+ lwsl_notice("%s: ns=%p (%s) changing state from %d to %d\n", __func__,
+ (void*)ns, ns->task ? ns->task->uuid : "null", ns->state, state);
+
ns->state = (uint8_t)state;
ns->state_changed = 1;
@@ -271,7 +276,10 @@ saib_set_ns_state(struct sai_nspawn *ns, int state)
if (!spm || !spm->ss)
return 0;
- return lws_ss_request_tx(spm->ss) ? -1 : 0;
+ int ret = lws_ss_request_tx(spm->ss) ? -1 : 0;
+ if (ret)
+ lwsl_notice("TRAP: saib_set_ns_state lws_ss_request_tx failed\n");
+ return ret;
}
/*
@@ -307,8 +315,10 @@ saib_queue_task_status_update(sai_plat_t *sp, struct sai_plat_server *spm,
rej.reason = (uint8_t)reason;
if (saib_srv_queue_json_fragments_helper(spm->ss, lsm_schema_json_task_rej,
- LWS_ARRAY_SIZE(lsm_schema_json_task_rej), &rej))
+ LWS_ARRAY_SIZE(lsm_schema_json_task_rej), &rej)) {
+ lwsl_notice("TRAP: saib_queue_task_status_update saib_srv_queue_json_fragments_helper failed\n");
return -1;
+ }
return 0;
}
@@ -318,6 +328,9 @@ saib_task_destroy(struct sai_nspawn *ns)
{
int n;
+ lwsl_notice("====== saib_task_destroy START (ns=%p, uuid=%s, spm=%p) ======\n",
+ (void*)ns, ns->task ? ns->task->uuid : "null", (void*)ns->spm);
+
lwsl_notice("%s: destroying task %s\n", __func__,
ns->task ? ns->task->uuid : "null");
@@ -331,11 +344,10 @@ saib_task_destroy(struct sai_nspawn *ns)
if (ns->spm) {
- if (saib_srv_queue_json_fragments_helper(ns->spm->ss,
+ saib_srv_queue_json_fragments_helper(ns->spm->ss,
lsm_schema_map_plat,
LWS_ARRAY_SIZE(lsm_schema_map_plat),
- &builder.sai_plat_owner))
- return;
+ &builder.sai_plat_owner);
/*
* If spm is holding on to us as the last reference point,
@@ -596,8 +608,14 @@ saib_start_artifact_upload(struct sai_nspawn *ns)
lws_dir_glob_t g;
int m;
- if (!ns->spm)
+ lwsl_notice("====== saib_start_artifact_upload START (ns=%p, uuid=%s, spm=%p) ======\n",
+ (void*)ns, ns->task ? ns->task->uuid : "null", (void*)ns->spm);
+
+ if (!ns->spm) {
+ lwsl_notice("%s: ns->spm is NULL, calling saib_task_destroy\n", __func__);
+ saib_task_destroy(ns);
return;
+ }
/*
* Let's look for any artifacts the saifile lists...
@@ -801,8 +819,11 @@ saib_consider_allocating_task(struct sai_plat_server *spm, lws_struct_args_t *a,
if (xns->task && !strcmp(xns->task->uuid, task->uuid)) {
lwsl_warn("%s: server offered task that's already running. State %d, artifacts %d, op %p\n",
__func__, xns->state, xns->count_artifacts, xns->op);
- saib_queue_task_status_update(sp, spm, task->uuid, 0,
- SAI_TASK_REASON_DUPE);
+ if (saib_queue_task_status_update(sp, spm, task->uuid, 0,
+ SAI_TASK_REASON_DUPE)) {
+ lwsl_notice("TRAP: saib_queue_task_status_update failed (DUPE)\n");
+ return -1;
+ }
saib_reassess_idle_situation();
return 0;
@@ -817,8 +838,10 @@ saib_consider_allocating_task(struct sai_plat_server *spm, lws_struct_args_t *a,
if (saib_can_accept_task(task, sp)) {
lwsl_warn("%s: builder rejects offered task\n", __func__);
if (saib_queue_task_status_update(sp, spm, task->uuid, 0,
- SAI_TASK_REASON_BUSY))
+ SAI_TASK_REASON_BUSY)) {
+ lwsl_notice("TRAP: saib_queue_task_status_update failed (BUSY)\n");
return -1;
+ }
saib_reassess_idle_situation();
return 0;
diff --git a/src/builder/b-ws-server.c b/src/builder/b-ws-server.c
index d371ec3..df02747 100644
--- a/src/builder/b-ws-server.c
+++ b/src/builder/b-ws-server.c
@@ -99,8 +99,10 @@ saib_srv_queue_tx(struct lws_ss_handle *h, void *buf, size_t len,
return -1;
}
- if (lws_ss_request_tx(h))
+ if (lws_ss_request_tx(h)) {
lwsl_ss_err(h, "failed to request tx");
+ return -1;
+ }
return 0;
}
@@ -117,7 +119,7 @@ saib_srv_queue_json_fragments_helper(struct lws_ss_handle *h,
js = lws_struct_json_serialize_create(map, map_entries, 0, object);
if (!js) {
- lwsl_warn("%s: failed to serialize\n", __func__);
+ lwsl_notice("TRAP: lws_struct_json_serialize_create failed\n");
return -1;
}
@@ -130,7 +132,7 @@ saib_srv_queue_json_fragments_helper(struct lws_ss_handle *h,
ssf |= LWSSS_FLAG_EOM;
break;
case LSJS_RESULT_ERROR:
- lwsl_warn("%s: serialization failed\n", __func__);
+ lwsl_notice("TRAP: lws_struct_json_serialize returned ERROR\n");
{
struct sai_plat_server *spm = (struct sai_plat_server *)lws_ss_to_user_object(h);
spm->tx_corrupted = 1;
@@ -138,8 +140,11 @@ saib_srv_queue_json_fragments_helper(struct lws_ss_handle *h,
return -1;
}
- if (saib_srv_queue_tx(h, buf + LWS_PRE, w, ssf) < 0)
+ if (saib_srv_queue_tx(h, buf + LWS_PRE, w, ssf) < 0) {
+ lwsl_notice("TRAP: saib_srv_queue_tx failed in helper\n");
+ lws_struct_json_serialize_destroy(&js);
return -1;
+ }
ssf &= ~((unsigned int)LWSSS_FLAG_SOM);
} while (!(ssf & LWSSS_FLAG_EOM));
@@ -175,6 +180,7 @@ saib_m_rx(void *userobj, const uint8_t *in, size_t len, int flags)
return LWSSSSRET_OK;
if (m < 0) {
+ lwsl_notice("TRAP: saib_m_rx lejp_parse failed m=%d\n", m);
lwsl_hexdump_err(in, len);
lwsl_err("%s: builder rx JSON decode failed '%s'\n",
__func__, lejp_error_to_string(m));
@@ -490,8 +496,12 @@ saib_m_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len,
}
}
- if (spm->bl_to_srv.owner.head)
- return lws_ss_request_tx(spm->ss);
+ if (spm->bl_to_srv.owner.head) {
+ lws_ss_state_return_t ret = lws_ss_request_tx(spm->ss);
+ if (ret != LWSSSSRET_OK)
+ lwsl_err("%s: lws_ss_request_tx returned %d\n", __func__, ret);
+ return ret;
+ }
return LWSSSSRET_OK;
}
@@ -533,6 +543,8 @@ cleanup_on_ss_disconnect(struct lws_dll2 *d, void *user)
if (ns->spm == spm) {
+ lwsl_notice("%s: orphaning task %s from disconnected spm\n", __func__, ns->task ? ns->task->uuid : "unknown");
+
/*
* This pss is about to go away, make sure the ns
* can't reference it any more no matter what happens
@@ -540,8 +552,10 @@ cleanup_on_ss_disconnect(struct lws_dll2 *d, void *user)
ns->spm = NULL;
- if (ns->op && ns->op->lsp)
+ if (ns->op && ns->op->lsp) {
+ lwsl_notice("%s: killing child process for task %s due to disconnect\n", __func__, ns->task ? ns->task->uuid : "unknown");
lws_spawn_piped_kill_child_process(ns->op->lsp);
+ }
}
} lws_end_foreach_dll_safe(d, d1);
diff --git a/src/power/p-http-api.c b/src/power/p-http-api.c
index 518b2a9..64ca326 100644
--- a/src/power/p-http-api.c
+++ b/src/power/p-http-api.c
@@ -422,7 +422,7 @@ local_srv_state(void *userobj, void *sh, lws_ss_constate_t state,
case LWSSSCS_SERVER_TXN:
lws_ss_get_metadata(lws_ss_from_user(g), "path", (const void **)&path, &len);
- lwsl_ss_user(lws_ss_from_user(g), "LWSSSCS_SERVER_TXN path '%.*s' (%d)", (int)len, path, (int)len);
+ // lwsl_ss_user(lws_ss_from_user(g), "LWSSSCS_SERVER_TXN path '%.*s' (%d)", (int)len, path, (int)len);
/*
* path is containing a string like "/power-off/b32"
diff --git a/src/server/s-comms.c b/src/server/s-comms.c
index 1113a61..da556c0 100644
--- a/src/server/s-comms.c
+++ b/src/server/s-comms.c
@@ -460,7 +460,14 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user,
case LWS_CALLBACK_CLOSED:
lwsac_free(&pss->query_ac);
- lwsl_wsi_user(wsi, "#### sai-server: CLOSED builder conn ####");
+ {
+ const unsigned char *cp = lws_get_close_payload(wsi);
+ int clen = lws_get_close_length(wsi);
+ if (clen)
+ lwsl_wsi_user(wsi, "#### sai-server: CLOSED builder conn (reason: %.*s) ####", clen, cp);
+ else
+ lwsl_wsi_user(wsi, "#### sai-server: CLOSED builder conn (no close payload) ####");
+ }
/* remove pss from vhd->builders (active connection list) */
lws_dll2_remove(&pss->same);
@@ -510,8 +517,10 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user,
// lwsl_wsi_notice(wsi, "rx from builder, len %d, : ss_flags: %d\n", (int)len, ssf);
- if (sais_ws_json_rx_builder(vhd, pss, in, len, ssf))
+ if (sais_ws_json_rx_builder(vhd, pss, in, len, ssf)) {
+ lwsl_err("%s: sais_ws_json_rx_builder returned error, dropping connection\n", __func__);
return -1;
+ }
if (!pss->announced) {
/*
@@ -533,14 +542,22 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user,
if (pss->is_power || pss->stay_owner.head)
return sais_power_tx(vhd, pss, buf, sizeof(buf));
- return sais_ws_json_tx_builder(vhd, pss, buf, sizeof(buf));
+ int ret = sais_ws_json_tx_builder(vhd, pss, buf, sizeof(buf));
+ if (ret != 0) {
+ lwsl_err("%s: sais_ws_json_tx_builder returned %d, dropping connection\n", __func__, ret);
+ }
+ return ret;
default:
passthru:
break;
}
- return lws_callback_http_dummy(wsi, reason, user, in, len);
+ int dummy_ret = lws_callback_http_dummy(wsi, reason, user, in, len);
+ if (dummy_ret != 0 && reason != LWS_CALLBACK_CLOSED && reason != LWS_CALLBACK_WSI_DESTROY) {
+ lwsl_err("%s: dummy returned %d for reason %d, dropping connection\n", __func__, dummy_ret, reason);
+ }
+ return dummy_ret;
}
const struct lws_protocols protocol_ws = {
diff --git a/src/server/s-private.h b/src/server/s-private.h
index 84883b0..f1aaa6d 100644
--- a/src/server/s-private.h
+++ b/src/server/s-private.h
@@ -434,6 +434,9 @@ sai_db_result_t
sais_task_clear_build_and_logs(struct vhd *vhd, const char *task_uuid, int from_rejection);
sai_db_result_t
+sais_task_remove_all_tries(struct vhd *vhd, const char *task_uuid);
+
+sai_db_result_t
sais_task_rebuild_last_step(struct vhd *vhd, const char *task_uuid);
int
diff --git a/src/server/s-task-helpers.c b/src/server/s-task-helpers.c
index c89fdaa..01f38b9 100644
--- a/src/server/s-task-helpers.c
+++ b/src/server/s-task-helpers.c
@@ -634,6 +634,58 @@ sais_task_clear_build_and_logs(struct vhd *vhd, const char *task_uuid, int from_
}
sai_db_result_t
+sais_task_remove_all_tries(struct vhd *vhd, const char *task_uuid)
+{
+ char esc[96], cmd[384], event_uuid[33];
+ sqlite3 *pdb = NULL;
+
+ lwsl_notice("%s: ================== task remove all tries %s\n", __func__, task_uuid);
+
+ if (!task_uuid[0])
+ return SAI_DB_RESULT_OK;
+
+ sai_task_uuid_to_event_uuid(event_uuid, task_uuid);
+
+ if (sai_event_db_ensure_open(vhd->context, &vhd->sqlite3_cache,
+ vhd->sqlite3_path_lhs, event_uuid, 0, &pdb)) {
+ lwsl_err("%s: unable to open event-specific database\n",
+ __func__);
+ return SAI_DB_RESULT_ERROR;
+ }
+
+ lws_sql_purify(esc, task_uuid, sizeof(esc));
+
+ sais_task_stop_on_builders(vhd, task_uuid);
+
+ lws_snprintf(cmd, sizeof(cmd), "DELETE FROM logs WHERE task_uuid='%s'", esc);
+ sqlite3_exec(pdb, cmd, NULL, NULL, NULL);
+
+ lws_snprintf(cmd, sizeof(cmd), "DELETE FROM artifacts WHERE task_uuid='%s'", esc);
+ sqlite3_exec(pdb, cmd, NULL, NULL, NULL);
+
+ lws_snprintf(cmd, sizeof(cmd), "DELETE FROM tasks WHERE uuid='%s' AND run > 0", esc);
+ sqlite3_exec(pdb, cmd, NULL, NULL, NULL);
+
+ lws_snprintf(cmd, sizeof(cmd),
+ "update tasks set state=%d,started=0,duration=0,build_step=0,builder_name='',builder='',server_name='' where uuid='%s' and run=0",
+ SAIES_WAITING, esc);
+ sqlite3_exec(pdb, cmd, NULL, NULL, NULL);
+
+ sai_event_db_close(&vhd->sqlite3_cache, &pdb);
+
+ sais_set_task_state(vhd, task_uuid, SAIES_WAITING, 0, 0);
+ sais_taskchange(vhd->h_ss_websrv, task_uuid, SAIES_WAITING);
+ sais_eventchange(vhd->h_ss_websrv, event_uuid, SAIES_WAITING);
+
+ lwsl_notice("%s: scheduling sul_central to find a new task\n", __func__);
+ lws_sul_schedule(vhd->context, 0, &vhd->sul_central, sais_central_cb, 1);
+
+ sais_platforms_with_tasks_pending(vhd);
+
+ return SAI_DB_RESULT_OK;
+}
+
+sai_db_result_t
sais_task_rebuild_last_step(struct vhd *vhd, const char *task_uuid)
{
char esc[96], cmd[384], event_uuid[33];
diff --git a/src/server/s-ws-builder.c b/src/server/s-ws-builder.c
index 2db6fc6..e846f66 100644
--- a/src/server/s-ws-builder.c
+++ b/src/server/s-ws-builder.c
@@ -1563,8 +1563,10 @@ sais_ws_json_tx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf,
js = lws_struct_json_serialize_create(lsm_schema_viewerstate,
LWS_ARRAY_SIZE(lsm_schema_viewerstate), 0, vs);
- if (!js)
+ if (!js) {
+ lwsl_err("%s: lws_struct_json_serialize_create failed for viewerstate\n", __func__);
return 1;
+ }
n = (int)lws_struct_json_serialize(js, p, lws_ptr_diff_size_t(end, p), &w);
lws_struct_json_serialize_destroy(&js);
@@ -1593,8 +1595,10 @@ sais_ws_json_tx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf,
js = lws_struct_json_serialize_create(lsm_schema_rebuild,
LWS_ARRAY_SIZE(lsm_schema_rebuild), 0, r);
- if (!js)
+ if (!js) {
+ lwsl_err("%s: lws_struct_json_serialize_create failed for rebuild\n", __func__);
return 1;
+ }
n = (int)lws_struct_json_serialize(js, p, lws_ptr_diff_size_t(end, p), &w);
lws_struct_json_serialize_destroy(&js);
@@ -1614,8 +1618,10 @@ sais_ws_json_tx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf,
js = lws_struct_json_serialize_create(lsm_schema_json_map_can,
LWS_ARRAY_SIZE(lsm_schema_json_map_can), 0, c);
- if (!js)
+ if (!js) {
+ lwsl_err("%s: lws_struct_json_serialize_create failed for task_cancel\n", __func__);
return 1;
+ }
n = (int)lws_struct_json_serialize(js, p, lws_ptr_diff_size_t(end, p), &w);
lws_struct_json_serialize_destroy(&js);
@@ -1632,8 +1638,10 @@ sais_ws_json_tx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf,
js = lws_struct_json_serialize_create(lsm_schema_openshell,
LWS_ARRAY_SIZE(lsm_schema_openshell), 0, os);
- if (!js)
+ if (!js) {
+ lwsl_err("%s: lws_struct_json_serialize_create failed for openshell\n", __func__);
return 1;
+ }
n = (int)lws_struct_json_serialize(js, p, lws_ptr_diff_size_t(end, p), &w);
lws_struct_json_serialize_destroy(&js);
@@ -1650,8 +1658,10 @@ sais_ws_json_tx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf,
js = lws_struct_json_serialize_create(lsm_schema_ptydata,
LWS_ARRAY_SIZE(lsm_schema_ptydata), 0, pd);
- if (!js)
+ if (!js) {
+ lwsl_err("%s: lws_struct_json_serialize_create failed for ptydata\n", __func__);
return 1;
+ }
n = (int)lws_struct_json_serialize(js, p, lws_ptr_diff_size_t(end, p), &w);
lws_struct_json_serialize_destroy(&js);
@@ -1735,8 +1745,10 @@ send_json:
// lwsl_hexdump_notice(start, p - start);
if (lws_write(pss->wsi, start, lws_ptr_diff_size_t(p, start),
- (enum lws_write_protocol)flags) < 0)
+ (enum lws_write_protocol)flags) < 0) {
+ lwsl_err("%s: lws_write failed for task allocation\n", __func__);
return -1;
+ }
if (pss->viewer_state_owner.head || pss->task_cancel_owner.head ||
pss->res_pending_reply_owner.count ||
@@ -1747,6 +1759,7 @@ send_json:
return 0;
bail:
+ lwsl_err("%s: bailing, returning 1\n", __func__);
lwsac_free(&task->ac_task_container);
free(task);
diff --git a/src/server/s-ws-web.c b/src/server/s-ws-web.c
index 3ca4cf3..2a6fb96 100644
--- a/src/server/s-ws-web.c
+++ b/src/server/s-ws-web.c
@@ -87,6 +87,8 @@ static const lws_struct_map_t lsm_schema_json_map[] = {
LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
/* shares struct */ "com.warmcat.sai.taskreset"),
LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
+ /* shares struct */ "com.warmcat.sai.taskremovealltries"),
+ LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
/* shares struct */ "com.warmcat.sai.taskrebuildlaststep"),
LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
/* shares struct */ "com.warmcat.sai.eventreset"),
@@ -122,6 +124,7 @@ static const lws_struct_map_t lsm_schema_json_map[] = {
enum {
SAIS_WS_WEBSRV_RX_TASKRESET,
+ SAIS_WS_WEBSRV_RX_TASKREMOVEALLTRIES,
SAIS_WS_WEBSRV_RX_TASKREBUILDLASTSTEP,
SAIS_WS_WEBSRV_RX_EVENTRESET,
SAIS_WS_WEBSRV_RX_EVENTDELETE,
@@ -481,6 +484,17 @@ websrvss_ws_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
lwsl_ss_err(m->ss, "taskreset failed");
break;
+ case SAIS_WS_WEBSRV_RX_TASKREMOVEALLTRIES:
+ ei = (sai_browse_rx_evinfo_t *)a.dest;
+ if (sais_validate_id(ei->event_hash, SAI_TASKID_LEN))
+ goto soft_error;
+
+ lwsl_ss_warn(m->ss, "SAIS_WS_WEBSRV_RX_TASKREMOVEALLTRIES: %s: received", ei->event_hash);
+ if (sais_task_remove_all_tries(m->vhd, ei->event_hash))
+ lwsl_ss_err(m->ss, "taskremovealltries failed");
+ break;
+
+
case SAIS_WS_WEBSRV_RX_TASKPAUSE:
ei = (sai_browse_rx_evinfo_t *)a.dest;
if (sais_validate_id(ei->event_hash, SAI_TASKID_LEN))
diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c
index 842565e..3a4919e 100644
--- a/src/web/w-ws-browser.c
+++ b/src/web/w-ws-browser.c
@@ -81,6 +81,8 @@ static const lws_struct_map_t lsm_schema_json_map_bwsrx[] = {
LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
/* shares struct */ "com.warmcat.sai.taskreset"),
LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
+ /* shares struct */ "com.warmcat.sai.taskremovealltries"),
+ LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
/* shares struct */ "com.warmcat.sai.taskrebuildlaststep"),
LSM_SCHEMA (sai_browse_rx_evinfo_t, NULL, lsm_browser_taskreset,
/* shares struct */ "com.warmcat.sai.eventreset"),
@@ -114,6 +116,7 @@ enum {
SAIM_WS_BROWSER_RX_TASKINFO,
SAIM_WS_BROWSER_RX_EVENTINFO,
SAIM_WS_BROWSER_RX_TASKRESET,
+ SAIM_WS_BROWSER_RX_TASKREMOVEALLTRIES,
SAIM_WS_BROWSER_RX_TASKREBUILDLASTSTEP,
SAIM_WS_BROWSER_RX_EVENTRESET,
SAIM_WS_BROWSER_RX_EVENTDELETE,
@@ -643,6 +646,7 @@ saiw_ws_json_rx_browser(struct vhd *vhd, struct pss *pss, uint8_t *buf,
if (!pss->authorized && (
a.top_schema_index == SAIM_WS_BROWSER_RX_TASKRESET ||
+ a.top_schema_index == SAIM_WS_BROWSER_RX_TASKREMOVEALLTRIES ||
a.top_schema_index == SAIM_WS_BROWSER_RX_TASKREBUILDLASTSTEP ||
a.top_schema_index == SAIM_WS_BROWSER_RX_EVENTRESET ||
a.top_schema_index == SAIM_WS_BROWSER_RX_EVENTDELETE ||
@@ -714,6 +718,7 @@ saiw_ws_json_rx_browser(struct vhd *vhd, struct pss *pss, uint8_t *buf,
goto ok;
+ case SAIM_WS_BROWSER_RX_TASKREMOVEALLTRIES:
case SAIM_WS_BROWSER_RX_TASKRESET:
/*
@@ -1157,6 +1162,13 @@ saiw_browser_queue_overview(struct vhd *vhd, struct pss *pss)
lws_start_foreach_dll(struct lws_dll2 *, pt, task_owner.head) {
t = lws_container_of(pt, sai_task_t, list);
+ if (lws_ptr_diff_size_t(end, p) < 128) {
+ saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, start,
+ lws_ptr_diff_size_t(p, start),
+ lws_write_ws_flags(LWS_WRITE_TEXT, 0, 0));
+ p = start;
+ }
+
if (task_index)
*p++ = ',';
@@ -1187,6 +1199,11 @@ saiw_browser_queue_overview(struct vhd *vhd, struct pss *pss)
do {
n = (int)lws_struct_json_serialize(js, (uint8_t *)p, lws_ptr_diff_size_t(end, p), &w);
switch (n) {
+ case LSJS_RESULT_ERROR:
+ lwsl_err("%s: json ser error for task\n", __func__);
+ lws_struct_json_serialize_destroy(&js);
+ return 1;
+
case LSJS_RESULT_FINISH:
lws_struct_json_serialize_destroy(&js);
p += w;