Skip to content

Commit 2686c6f

Browse files
committed
CA-388210: SMAPIv3 debugging: log PID
Log PID on successful and failed operations, and log full cmdline for newly spawned processes. This can be used to debug stuck scripts, so that we know which invocation is the one that is stuck. Signed-off-by: Edwin Török <edwin.torok@cloud.com>
1 parent 77b8ae9 commit 2686c6f

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

ocaml/xapi-storage-script/lib.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ module Process = struct
131131

132132
type t = {
133133
exit_status: (unit, exit_or_signal) Result.t
134+
; pid: int
134135
; stdout: string
135136
; stderr: string
136137
}
@@ -176,6 +177,7 @@ module Process = struct
176177
let run ~env ~prog ~args ~input =
177178
let ( let@ ) f x = f x in
178179
let@ p = with_process ~env ~prog ~args in
180+
let pid = p#pid in
179181
let sender = send p#stdin input in
180182
let receiver_out = receive p#stdout in
181183
let receiver_err = receive p#stderr in
@@ -185,7 +187,7 @@ module Process = struct
185187
Lwt.both sender receiver >>= fun ((), (stdout, stderr)) ->
186188
p#status >>= fun status ->
187189
let exit_status = Output.exit_or_signal_of_unix status in
188-
Lwt.return {Output.exit_status; stdout; stderr}
190+
Lwt.return {Output.exit_status; pid; stdout; stderr}
189191
)
190192
(function
191193
| Lwt.Canceled as exn ->

ocaml/xapi-storage-script/lib.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module Process : sig
6565

6666
type t = {
6767
exit_status: (unit, exit_or_signal) result
68+
; pid: int
6869
; stdout: string
6970
; stderr: string
7071
}
@@ -78,7 +79,7 @@ module Process : sig
7879
-> Output.t Lwt.t
7980
(** Runs a cli program, writes [input] into its stdin, then closing the fd,
8081
and finally waits for the program to finish and returns the exit status,
81-
its stdout and stderr. *)
82+
the pid, and its stdout and stderr. *)
8283
end
8384

8485
module DirWatcher : sig

ocaml/xapi-storage-script/main.ml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,8 @@ let fork_exec_rpc :
477477
)
478478
>>>= fun input ->
479479
let input = compat_in input |> Jsonrpc.to_string in
480+
debug (fun m -> m "Running %s" @@ Filename.quote_command script_name args)
481+
>>= fun () ->
480482
Process.run ~env ~prog:script_name ~args ~input >>= fun output ->
481483
let fail_because ~cause description =
482484
fail
@@ -500,12 +502,13 @@ let fork_exec_rpc :
500502
with
501503
| Error _ ->
502504
error (fun m ->
503-
m "%s failed and printed bad error json: %s" script_name
504-
output.Process.Output.stdout
505+
m "%s[%d] failed and printed bad error json: %s" script_name
506+
output.pid output.Process.Output.stdout
505507
)
506508
>>= fun () ->
507509
error (fun m ->
508-
m "%s failed, stderr: %s" script_name output.Process.Output.stderr
510+
m "%s[%d] failed, stderr: %s" script_name output.pid
511+
output.Process.Output.stderr
509512
)
510513
>>= fun () ->
511514
fail_because "non-zero exit and bad json on stdout"
@@ -516,12 +519,12 @@ let fork_exec_rpc :
516519
with
517520
| Error _ ->
518521
error (fun m ->
519-
m "%s failed and printed bad error json: %s" script_name
520-
output.Process.Output.stdout
522+
m "%s[%d] failed and printed bad error json: %s" script_name
523+
output.pid output.Process.Output.stdout
521524
)
522525
>>= fun () ->
523526
error (fun m ->
524-
m "%s failed, stderr: %s" script_name
527+
m "%s[%d] failed, stderr: %s" script_name output.pid
525528
output.Process.Output.stderr
526529
)
527530
>>= fun () ->
@@ -532,7 +535,9 @@ let fork_exec_rpc :
532535
)
533536
)
534537
| Error (Signal signal) ->
535-
error (fun m -> m "%s caught a signal and failed" script_name)
538+
error (fun m ->
539+
m "%s[%d] caught a signal and failed" script_name output.pid
540+
)
536541
>>= fun () -> fail_because "signalled" ~cause:(Signal.to_string signal)
537542
| Ok () -> (
538543
(* Parse the json on stdout. We get back a JSON-RPC
@@ -544,8 +549,8 @@ let fork_exec_rpc :
544549
with
545550
| Error _ ->
546551
error (fun m ->
547-
m "%s succeeded but printed bad json: %s" script_name
548-
output.Process.Output.stdout
552+
m "%s[%d] succeeded but printed bad json: %s" script_name
553+
output.pid output.Process.Output.stdout
549554
)
550555
>>= fun () ->
551556
fail
@@ -554,7 +559,8 @@ let fork_exec_rpc :
554559
)
555560
| Ok response ->
556561
info (fun m ->
557-
m "%s succeeded: %s" script_name output.Process.Output.stdout
562+
m "%s[%d] succeeded: %s" script_name output.pid
563+
output.Process.Output.stdout
558564
)
559565
>>= fun () ->
560566
let response = compat_out response in

ocaml/xapi-storage-script/test_lib.ml

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,20 @@ let test_run_status =
103103
let module P = Process in
104104
let test () =
105105
let* output = P.run ~prog:"true" ~args:[] ~input:"" ~env:[] in
106-
let expected = P.Output.{exit_status= Ok (); stdout= ""; stderr= ""} in
106+
let expected =
107+
P.Output.{exit_status= Ok (); pid= output.pid; stdout= ""; stderr= ""}
108+
in
107109
Alcotest.(check output_c) "Exit status is correct" expected output ;
108110

109111
let* output = P.run ~prog:"false" ~args:[] ~input:"" ~env:[] in
110112
let expected =
111-
P.Output.{exit_status= Error (Exit_non_zero 1); stdout= ""; stderr= ""}
113+
P.Output.
114+
{
115+
exit_status= Error (Exit_non_zero 1)
116+
; pid= output.pid
117+
; stdout= ""
118+
; stderr= ""
119+
}
112120
in
113121
Alcotest.(check output_c) "Exit status is correct" expected output ;
114122

@@ -121,15 +129,24 @@ let test_run_output =
121129
let test () =
122130
let content = "@@@@@@" in
123131
let* output = P.run ~prog:"cat" ~args:["-"] ~input:content ~env:[] in
124-
let expected = P.Output.{exit_status= Ok (); stdout= content; stderr= ""} in
132+
let expected =
133+
P.Output.
134+
{exit_status= Ok (); pid= output.pid; stdout= content; stderr= ""}
135+
in
125136
Alcotest.(check output_c) "Stdout is correct" expected output ;
126137

127138
let* output = P.run ~prog:"cat" ~args:[content] ~input:content ~env:[] in
128139
let stderr =
129140
Printf.sprintf "cat: %s: No such file or directory\n" content
130141
in
131142
let expected =
132-
P.Output.{exit_status= Error (Exit_non_zero 1); stdout= ""; stderr}
143+
P.Output.
144+
{
145+
exit_status= Error (Exit_non_zero 1)
146+
; pid= output.pid
147+
; stdout= ""
148+
; stderr
149+
}
133150
in
134151
Alcotest.(check output_c) "Stderr is correct" expected output ;
135152
Lwt.return ()

0 commit comments

Comments
 (0)