Skip to content

Update feature/perf with latest blocker fixes #6237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
87013f1
CA-364194: use timespans for script timeouts
psafont Oct 12, 2022
5689150
CA-403700 use iso9660 file system for updates
Dec 17, 2024
02ca33e
CA-404512: Add feature flag to the new clustering interface
Vincent-lau Jan 8, 2025
f2f6d20
CA-404512: Add feature flag to the new clustering interface (#6217)
Vincent-lau Jan 13, 2025
d8ac4d9
CA-403700 use iso9660 file system for updates (#6216)
robhoes Jan 13, 2025
f58d8d3
CA-364194: use timespans for script timeouts (#6200)
robhoes Jan 14, 2025
142137d
Remove unused Unixext.Direct module
robhoes Jan 14, 2025
7552baa
Remove unused Unixext.Direct module (#6224)
robhoes Jan 14, 2025
8992f9d
github: update release for ubuntu 24.04
psafont Jan 15, 2025
706b3b2
github: update release for ubuntu 24.04 (#6231)
last-genius Jan 15, 2025
de7e1eb
github: remove dependency of python wheel's on dune
psafont Jan 15, 2025
325febf
github: remove dependency of python wheel's on dune (#6232)
psafont Jan 15, 2025
aac5802
CA-404640 XSI-1781 accept in PEM key/cert in any order
Jan 14, 2025
609be92
CA-404640 XSI-1781 bring back fail-06.pem
Jan 14, 2025
5b86063
Log proper names for POSIX signals
psafont Jan 14, 2025
c0fbb69
Debug: add pretty-printing function for signals
psafont Jan 14, 2025
b41cfea
CA-404640 XSI-1781 accept in PEM key/cert in any order (#6227)
lindig Jan 16, 2025
0326d27
CA-404597: rrd/lib_test - Verify that RRD handles non-rate data sourc…
Jan 15, 2025
6c1e7ea
Log proper names for POSIX signals (#6228)
psafont Jan 16, 2025
73ca3cc
CA-404597: rrd - Pass Gauge and Absolute data source values as-is
Jan 16, 2025
43d01ca
CA-404597 - rrd: Fix incorrect processing of Gauge and Absolute data …
last-genius Jan 16, 2025
731ede7
CA-404591 - rrd: Do not lose precision when converting floats to strings
Jan 17, 2025
1e5114c
CA-404591 - rrd: Do not lose precision when converting floats to stri…
edwintorok Jan 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ jobs:
python-version: "3.x"

- name: Install build dependencies
run: |
pip install build
sudo apt-get install ocaml dune libfindlib-ocaml-dev libdune-ocaml-dev libcmdliner-ocaml-dev
run: pip install build

- name: Generate python package for XenAPI
run: |
./configure --xapi_version=${{ github.ref_name }}
echo "export XAPI_VERSION=${{ github.ref_name }}" > config.mk
make python

- name: Store python distribution artifacts
Expand Down
38 changes: 19 additions & 19 deletions doc/content/design/coverage/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ revision: 2

We would like to add optional coverage profiling to existing [OCaml]
projects in the context of [XenServer] and [XenAPI]. This article
presents how we do it.
presents how we do it.

Binaries instrumented for coverage profiling in the XenServer project
need to run in an environment where several services act together as
Expand All @@ -21,7 +21,7 @@ isolation.
To build binaries with coverage profiling, do:

./configure --enable-coverage
make
make

Binaries will log coverage data to `/tmp/bisect*.out` from which a
coverage report can be generated in `coverage/`:
Expand All @@ -38,7 +38,7 @@ and logs during execution data to in-memory data structures. Before an
instrumented binary terminates, it writes the logged data to a file.
This data can then be analysed with the `bisect-ppx-report` tool, to
produce a summary of annotated code that highlights what part of a
codebase was executed.
codebase was executed.

[BisectPPX] has several desirable properties:

Expand All @@ -65,13 +65,13 @@ abstracted by OCamlfind (OCaml's library manager) and OCamlbuild

# build it with instrumentation from bisect_ppx
ocamlbuild -use-ocamlfind -pkg bisect_ppx -pkg unix example.native

# execute it - generates files ./bisect*.out
./example.native

# generate report
bisect-ppx-report -I _build -html coverage bisect000*

# view coverage/index.html

Summary:
Expand All @@ -86,7 +86,7 @@ will be instrumented during compilation. Behind the scenes `ocamlfind`
makes sure that the compiler uses a preprocessing step that instruments
the code.

## Signal Handling
## Signal Handling

During execution the code instrumentation leads to the collection of
data. This code registers a function with `at_exit` that writes the data
Expand All @@ -98,7 +98,7 @@ terminated by receiving the `TERM` signal, a signal handler must be
installed:

let stop signal =
printf "caught signal %d\n" signal;
printf "caught signal %a\n" Debug.Pp.signal signal;
exit 0

Sys.set_signal Sys.sigterm (Sys.Signal_handle stop)
Expand Down Expand Up @@ -149,8 +149,8 @@ environment variable. This can happen on the command line:

BISECT_FILE=/tmp/example ./example.native

In the context of XenServer we could do this in startup scripts.
However, we added a bit of code
In the context of XenServer we could do this in startup scripts.
However, we added a bit of code

val Coverage.init: string -> unit

Expand All @@ -176,12 +176,12 @@ Goals for instrumentation are:

* what files are instrumented should be obvious and easy to manage
* instrumentation must be optional, yet easy to activate
* avoid methods that require to keep several files in sync like multiple
* avoid methods that require to keep several files in sync like multiple
`_oasis` files
* avoid separate Git branches for instrumented and non-instrumented
code

In the ideal case, we could introduce a configuration switch
In the ideal case, we could introduce a configuration switch
`./configure --enable-coverage` that would prepare compilation for
coverage instrumentation. While [Oasis] supports the creation of such
switches, they cannot be used to control build dependencies like
Expand All @@ -196,7 +196,7 @@ rules in file `_tags.coverage` that cause files to be instrumented:

leads to the execution of this code during preparation:

coverage: _tags _tags.coverage
coverage: _tags _tags.coverage
test ! -f _tags.orig && mv _tags _tags.orig || true
cat _tags.coverage _tags.orig > _tags

Expand All @@ -207,7 +207,7 @@ could be tweaked to instrument only some files:
<**/*.native>: pkg_bisect_ppx

When `make coverage` is not called, these rules are not active and
hence, code is not instrumented for coverage. We believe that this
hence, code is not instrumented for coverage. We believe that this
solution to control instrumentation meets the goals from above. In
particular, what files are instrumented and when is controlled by very
few lines of declarative code that lives in the main repository of a
Expand All @@ -226,14 +226,14 @@ coverage analysis are:
The `_oasis` file bundles the files under `profiling/` into an internal
library which executables then depend on:

# Support files for profiling
# Support files for profiling
Library profiling
CompiledObject: best
Path: profiling
Install: false
Findlibname: profiling
Modules: Coverage
BuildDepends:
BuildDepends:

Executable set_domain_uuid
CompiledObject: best
Expand All @@ -243,16 +243,16 @@ library which executables then depend on:
MainIs: set_domain_uuid.ml
Install: false
BuildDepends:
xenctrl,
uuidm,
xenctrl,
uuidm,
cmdliner,
profiling # <-- here

The `Makefile` target `coverage` primes the project for a profiling build:

# make coverage - prepares for building with coverage analysis

coverage: _tags _tags.coverage
coverage: _tags _tags.coverage
test ! -f _tags.orig && mv _tags _tags.orig || true
cat _tags.coverage _tags.orig > _tags

Expand Down
2 changes: 2 additions & 0 deletions ocaml/forkexecd/lib/dune
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
(wrapped false)
(libraries
astring
clock
fd-send-recv
mtime
rpclib.core
rpclib.json
rpclib.xml
Expand Down
19 changes: 12 additions & 7 deletions ocaml/forkexecd/lib/forkhelpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ let safe_close_and_exec ?tracing ?env stdin stdout stderr
close_fds

let execute_command_get_output_inner ?tracing ?env ?stdin
?(syslog_stdout = NoSyslogging) ?(redirect_stderr_to_stdout = false)
?(timeout = -1.0) cmd args =
?(syslog_stdout = NoSyslogging) ?(redirect_stderr_to_stdout = false) timeout
cmd args =
let to_close = ref [] in
let close fd =
if List.mem fd !to_close then (
Expand Down Expand Up @@ -354,8 +354,13 @@ let execute_command_get_output_inner ?tracing ?env ?stdin
close wr
)
stdinandpipes ;
if timeout > 0. then
Unix.setsockopt_float sock Unix.SO_RCVTIMEO timeout ;
( match timeout with
| Some span ->
let timeout = Clock.Timer.span_to_s span in
Unix.setsockopt_float sock Unix.SO_RCVTIMEO timeout
| None ->
()
) ;
with_tracing ~tracing ~name:"Forkhelpers.waitpid" @@ fun _ ->
try waitpid (sock, pid)
with Unix.(Unix_error ((EAGAIN | EWOULDBLOCK), _, _)) ->
Expand All @@ -380,12 +385,12 @@ let execute_command_get_output_inner ?tracing ?env ?stdin
let execute_command_get_output ?tracing ?env ?(syslog_stdout = NoSyslogging)
?(redirect_stderr_to_stdout = false) ?timeout cmd args =
with_tracing ~tracing ~name:__FUNCTION__ @@ fun tracing ->
execute_command_get_output_inner ?tracing ?env ?stdin:None ?timeout
~syslog_stdout ~redirect_stderr_to_stdout cmd args
execute_command_get_output_inner ?tracing ?env ?stdin:None ~syslog_stdout
~redirect_stderr_to_stdout timeout cmd args

let execute_command_get_output_send_stdin ?tracing ?env
?(syslog_stdout = NoSyslogging) ?(redirect_stderr_to_stdout = false)
?timeout cmd args stdin =
with_tracing ~tracing ~name:__FUNCTION__ @@ fun tracing ->
execute_command_get_output_inner ?tracing ?env ~stdin ~syslog_stdout
~redirect_stderr_to_stdout ?timeout cmd args
~redirect_stderr_to_stdout timeout cmd args
4 changes: 2 additions & 2 deletions ocaml/forkexecd/lib/forkhelpers.mli
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ val execute_command_get_output :
-> ?env:string array
-> ?syslog_stdout:syslog_stdout
-> ?redirect_stderr_to_stdout:bool
-> ?timeout:float
-> ?timeout:Mtime.Span.t
-> string
-> string list
-> string * string
Expand All @@ -61,7 +61,7 @@ val execute_command_get_output_send_stdin :
-> ?env:string array
-> ?syslog_stdout:syslog_stdout
-> ?redirect_stderr_to_stdout:bool
-> ?timeout:float
-> ?timeout:Mtime.Span.t
-> string
-> string list
-> string
Expand Down
4 changes: 2 additions & 2 deletions ocaml/forkexecd/src/child.ml
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ let report_child_exit comms_sock args child_pid status =
Fe.WEXITED n
| Unix.WSIGNALED n ->
log_failure args child_pid
(Printf.sprintf "exited with signal: %s" (Unixext.string_of_signal n)) ;
(Printf.sprintf "exited with signal: %a" Debug.Pp.signal n) ;
Fe.WSIGNALED n
| Unix.WSTOPPED n ->
log_failure args child_pid
(Printf.sprintf "stopped with signal: %s" (Unixext.string_of_signal n)) ;
(Printf.sprintf "stopped with signal: %a" Debug.Pp.signal n) ;
Fe.WSTOPPED n
in
let result = Fe.Finished pr in
Expand Down
2 changes: 1 addition & 1 deletion ocaml/forkexecd/test/dune
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(executable
(modes exe)
(name fe_test)
(libraries forkexec uuid xapi-stdext-unix fd-send-recv))
(libraries fmt forkexec mtime clock mtime.clock.os uuid xapi-stdext-unix fd-send-recv))

(rule
(alias runtest)
Expand Down
44 changes: 26 additions & 18 deletions ocaml/forkexecd/test/fe_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,6 @@ let one fds x =
:: string_of_int (fds - (x.max_extra - number_of_extra))
:: shuffle cmdline_names
in
(* Printf.fprintf stderr "stdin = %s\n" (if x.stdin then "Some" else "None");
Printf.fprintf stderr "stdout = %s\n" (if x.stdout then "Some" else "None");
Printf.fprintf stderr "stderr = %s\n" (if x.stderr then "Some" else "None");
List.iter (fun (uuid, _) -> Printf.fprintf stderr "uuid %s -> stdin\n" uuid) table;
Printf.fprintf stderr "%s %s\n" exe (String.concat " " args);
*)
Forkhelpers.waitpid_fail_if_bad_exit
(Forkhelpers.safe_close_and_exec
(if x.stdin then Some fd else None)
Expand All @@ -129,26 +123,43 @@ let one fds x =
table exe args
)

type in_range = In_range | Longer | Shorter

let in_range ~e:leeway ~around span =
let upper = Mtime.Span.add around leeway in
if Clock.Timer.span_is_shorter ~than:around span then
Shorter
else if Clock.Timer.span_is_longer ~than:upper span then
Longer
else
In_range

let test_delay () =
let start = Unix.gettimeofday () in
let start = Mtime_clock.counter () in
let args = ["sleep"] in
(* Need to have fractional part because some internal usage split integer
and fractional and do computation.
Better to have a high fractional part (> 0.5) to more probably exceed
the unit.
*)
let timeout = 1.7 in
let timeout = Mtime.Span.(1700 * ms) in
try
Forkhelpers.execute_command_get_output ~timeout exe args |> ignore ;
fail "Failed to timeout"
with
| Forkhelpers.Subprocess_timeout ->
let elapsed = Unix.gettimeofday () -. start in
Printf.printf "Caught timeout exception after %f seconds\n%!" elapsed ;
if elapsed < timeout then
failwith "Process exited too soon" ;
if elapsed > timeout +. 0.2 then
failwith "Excessive time elapsed"
| Forkhelpers.Subprocess_timeout -> (
let elapsed = Mtime_clock.count start in
Printf.printf "Caught timeout exception after %s seconds\n%!"
Fmt.(to_to_string Mtime.Span.pp elapsed) ;

match in_range ~e:Mtime.Span.(200 * ms) ~around:timeout elapsed with
| In_range ->
()
| Shorter ->
failwith "Process exited too soon"
| Longer ->
failwith "Process took too long to exit"
)
| e ->
fail "Failed with unexpected exception: %s" (Printexc.to_string e)

Expand Down Expand Up @@ -289,9 +300,6 @@ let slave = function
)
fds ;
(* Check that we have the expected number *)
(*
Printf.fprintf stderr "%s %d\n" total_fds (List.length present - 1)
*)
if total_fds <> List.length filtered then
fail "Expected %d fds; /proc/self/fd has %d: %s" total_fds
(List.length filtered) ls
Expand Down
Loading
Loading