Skip to content

Commit f8c5c1d

Browse files
BUG/MINOR: mworker/cli: fix show proc pagination using reload counter
After commit 594408c, related to ticket haproxy#3204, the "show proc" logic has been fixed to be able to print more than 202 processes. However, this fix can lead to the omission of entries in case they have the same timestamp. To fix this, we use the unique reload counter instead of the timestamp. On partial flush, set ctx->next_reload = child->reloads. On resume skip entries with child->reloads >= ctx->next_reload. Finally, we clear ctx->next_reload at the end of a complete dump so subsequent show proc starts from the top.
1 parent e8b257d commit f8c5c1d

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

src/mworker.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ void mworker_cleanup_proc()
807807

808808
struct cli_showproc_ctx {
809809
int debug;
810-
int next_uptime; /* uptime must be greater than this value */
810+
int next_reload; /* reload number to resume from, 0 = from the beginning */
811811
};
812812

813813
/* Displays workers and processes */
@@ -825,7 +825,7 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
825825

826826
chunk_reset(&trash);
827827

828-
if (ctx->next_uptime == 0) {
828+
if (ctx->next_reload == 0) {
829829
memprintf(&reloadtxt, "%d [failed: %d]", proc_self->reloads, proc_self->failedreloads);
830830
chunk_printf(&trash, "#%-14s %-15s %-15s %-15s %-15s", "<PID>", "<type>", "<reloads>", "<uptime>", "<version>");
831831
if (ctx->debug)
@@ -843,12 +843,12 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
843843
ha_free(&uptime);
844844

845845
/* displays current processes */
846-
if (ctx->next_uptime == 0)
846+
if (ctx->next_reload == 0)
847847
chunk_appendf(&trash, "# workers\n");
848848
list_for_each_entry(child, &proc_list, list) {
849849

850850
/* don't display current worker if we only need the next ones */
851-
if (ctx->next_uptime != 0)
851+
if (ctx->next_reload != 0)
852852
continue;
853853

854854
up = date.tv_sec - child->timestamp;
@@ -874,15 +874,16 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
874874
return 0;
875875

876876
/* displays old processes */
877-
if (old || ctx->next_uptime) { /* there's more */
878-
if (ctx->next_uptime == 0)
877+
if (old || ctx->next_reload) { /* there's more */
878+
if (ctx->next_reload == 0)
879879
chunk_appendf(&trash, "# old workers\n");
880880
list_for_each_entry(child, &proc_list, list) {
881881
up = date.tv_sec - child->timestamp;
882882
if (up <= 0) /* must never be negative because of clock drift */
883883
up = 0;
884884

885-
if (child->timestamp < ctx->next_uptime)
885+
/* If we're resuming, skip entries that were already printed (reload >= ctx->next_reload) */
886+
if (ctx->next_reload && child->reloads >= ctx->next_reload)
886887
continue;
887888

888889
if (!(child->options & PROC_O_TYPE_WORKER))
@@ -895,17 +896,21 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
895896
chunk_appendf(&trash, "\t\t %-15d %-15d", child->ipc_fd[0], child->ipc_fd[1]);
896897
chunk_appendf(&trash, "\n");
897898
ha_free(&uptime);
898-
}
899899

900-
/* start from there if there's not enough place */
901-
ctx->next_uptime = child->timestamp;
900+
/* Try to flush so we can resume after this reload on next page if the buffer is full. */
901+
if (applet_putchk(appctx, &trash) == -1) {
902+
/* resume at this reload (exclude it on next pass) */
903+
ctx->next_reload = child->reloads; /* resume after entries >= this reload */
904+
return 0;
905+
}
906+
chunk_reset(&trash);
907+
}
902908

903-
if (applet_putchk(appctx, &trash) == -1)
904-
return 0;
905909
}
906910
}
907911

908-
/* dump complete */
912+
/* dump complete: reset resume cursor so next 'show proc' starts from the top */
913+
ctx->next_reload = 0;
909914
return 1;
910915
}
911916

0 commit comments

Comments
 (0)