Skip to content

Commit

Permalink
CP-28369: Remove Unixext.daemonize (#6026)
Browse files Browse the repository at this point in the history
Last usage of `Unixext.daemonize` was in `cdrommon`, drop it and move
the daemon to be fully handled by systemd (instead of `type=forking`).

`cdrommon` service is only started by storage scripts, and I'm not sure
if it's tested at all, but these changes pass BST+BVT.
  • Loading branch information
last-genius authored Oct 1, 2024
2 parents 6e16163 + c261733 commit e90a98e
Show file tree
Hide file tree
Showing 14 changed files with 8 additions and 119 deletions.
1 change: 0 additions & 1 deletion ocaml/cdrommon/cdrommon.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,5 @@ let () =
Printf.eprintf "usage: %s <cdrompath>\n" Sys.argv.(0) ;
exit 1
) ;
Xapi_stdext_unix.Unixext.daemonize () ;
(* check every 2 seconds *)
check 2 Sys.argv.(1)
21 changes: 0 additions & 21 deletions ocaml/libs/xapi-stdext/lib/xapi-stdext-unix/unixext.ml
Original file line number Diff line number Diff line change
Expand Up @@ -94,27 +94,6 @@ let with_file file mode perms f =
(fun () -> f fd)
(fun () -> Unix.close fd)

(* !! Must call this before spawning any threads !! *)

(** daemonize a process *)
let daemonize () =
match Unix.fork () with
| 0 -> (
if Unix.setsid () == -1 then
failwith "Unix.setsid failed" ;
match Unix.fork () with
| 0 ->
with_file "/dev/null" [Unix.O_WRONLY] 0 (fun nullfd ->
Unix.close Unix.stdin ;
Unix.dup2 nullfd Unix.stdout ;
Unix.dup2 nullfd Unix.stderr
)
| _ ->
exit 0
)
| _ ->
exit 0

exception Break

let lines_fold f start input =
Expand Down
4 changes: 1 addition & 3 deletions ocaml/libs/xapi-stdext/lib/xapi-stdext-unix/unixext.mli
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ val pidfile_write : string -> unit

val pidfile_read : string -> int option

val daemonize : unit -> unit

val with_file :
string
-> Unix.open_flag list
Expand Down Expand Up @@ -262,7 +260,7 @@ val test_open : int -> unit
to [Xapi_stdext_unix.Unixext.select] that use file descriptors, because such calls will then immediately fail.
This assumes that [ulimit -n] has been suitably increased in the test environment.
Can only be called once in a program, and will raise an exception otherwise.
The file descriptors will stay open until the program exits.
Expand Down
14 changes: 5 additions & 9 deletions ocaml/networkd/bin/networkd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,11 @@ let () =
~rpc_fn:(Idl.Exn.server Network_server.S.implementation)
()
in
Xcp_service.maybe_daemonize
~start_fn:(fun () ->
Debug.set_facility Syslog.Local5 ;
(* We should make the following configurable *)
Debug.disable "http" ;
handle_shutdown () ;
Debug.with_thread_associated "main" start server
)
() ;
Debug.set_facility Syslog.Local5 ;
(* We should make the following configurable *)
Debug.disable "http" ;
handle_shutdown () ;
Debug.with_thread_associated "main" start server ;
let module Daemon = Xapi_stdext_unix.Unixext.Daemon in
if Daemon.systemd_notify Daemon.State.Ready then
()
Expand Down
3 changes: 0 additions & 3 deletions ocaml/squeezed/src/squeezed.ml
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ let _ =
~rpc_fn:(Idl.Exn.server S.implementation)
()
in
maybe_daemonize () ;
(* NB Initialise the xenstore connection after daemonising, otherwise we lose
our connection *)
let _ = Thread.create Memory_server.record_boot_time_host_free_memory () in
let rpc_server = Thread.create Xcp_service.serve_forever server in
Memory_server.start_balance_thread balance_check_interval ;
Expand Down
57 changes: 0 additions & 57 deletions ocaml/xapi-idl/lib/xcp_service.ml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ let log_destination = ref "syslog:daemon"

let log_level = ref Syslog.Debug

let daemon = ref false

let have_daemonized () = Unix.getppid () = 1

let common_prefix = "org.xen.xapi."

let finally f g =
Expand Down Expand Up @@ -196,11 +192,6 @@ let common_options =
, (fun () -> !log_destination)
, "Where to write log messages"
)
; ( "daemon"
, Arg.Bool (fun x -> daemon := x)
, (fun () -> string_of_bool !daemon)
, "True if we are to daemonise"
)
; ( "disable-logging-for"
, Arg.String
(fun x ->
Expand Down Expand Up @@ -552,8 +543,6 @@ let http_handler call_of_string string_of_response process s =
Response.write (fun _t -> ()) response oc
)

let ign_int (t : int) = ignore t

let default_raw_fn rpc_fn s =
http_handler Xmlrpc.call_of_string Xmlrpc.string_of_response rpc_fn s

Expand Down Expand Up @@ -635,52 +624,6 @@ let serve_forever = function
let rec forever () = Thread.delay 3600. ; forever () in
forever ()

let pidfile_write filename =
let fd =
Unix.openfile filename [Unix.O_WRONLY; Unix.O_CREAT; Unix.O_TRUNC] 0o640
in
finally
(fun () ->
let pid = Unix.getpid () in
let buf = string_of_int pid ^ "\n" |> Bytes.of_string in
let len = Bytes.length buf in
if Unix.write fd buf 0 len <> len then
failwith "pidfile_write failed"
)
(fun () -> Unix.close fd)

(* Cf Stevens et al, Advanced Programming in the UNIX Environment,
Section 13.3 *)
let daemonize ?start_fn () =
if not (have_daemonized ()) then
ign_int (Unix.umask 0) ;
match Unix.fork () with
| 0 -> (
if Unix.setsid () == -1 then failwith "Unix.setsid failed" ;
Sys.set_signal Sys.sighup Sys.Signal_ignore ;
match Unix.fork () with
| 0 ->
Option.iter (fun fn -> fn ()) start_fn ;
Unix.chdir "/" ;
mkdir_rec (Filename.dirname !pidfile) 0o755 ;
pidfile_write !pidfile ;
let nullfd = Unix.openfile "/dev/null" [Unix.O_RDWR] 0 in
Unix.dup2 nullfd Unix.stdin ;
Unix.dup2 nullfd Unix.stdout ;
Unix.dup2 nullfd Unix.stderr ;
Unix.close nullfd
| _ ->
exit 0
)
| _ ->
exit 0

let maybe_daemonize ?start_fn () =
if !daemon then
daemonize ?start_fn ()
else
Option.iter (fun fn -> fn ()) start_fn

let cli ~name ~doc ~version ~cmdline_gen =
let default = Term.(ret (const (fun _ -> `Help (`Pager, None)) $ const ())) in
let version =
Expand Down
6 changes: 0 additions & 6 deletions ocaml/xapi-idl/lib/xcp_service.mli
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,8 @@ val make :

val serve_forever : server -> unit

val daemon : bool ref

val loglevel : unit -> Syslog.level

val daemonize : ?start_fn:(unit -> unit) -> unit -> unit

val maybe_daemonize : ?start_fn:(unit -> unit) -> unit -> unit

val cli :
name:string
-> doc:string
Expand Down
5 changes: 0 additions & 5 deletions ocaml/xapi-storage-script/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2043,11 +2043,6 @@ let _ =
in
configure2 ~name:"xapi-script-storage" ~version:Xapi_version.version
~doc:description ~resources ~options () ;
if !Xcp_service.daemon then (
Xcp_service.maybe_daemonize () ;
use_syslog := true ;
info "Daemonisation successful."
) ;
let run () =
let ( let* ) = ( >>= ) in
let* observer_enabled = observer_is_component_enabled () in
Expand Down
2 changes: 0 additions & 2 deletions ocaml/xapi/xapi_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ let _ =
Debug.set_facility Syslog.Local5 ;
Sys.enable_runtime_warnings true ;
init_args () ;
(* need to read args to find out whether to daemonize or not *)
Xcp_service.maybe_daemonize () ;
(* Disable logging for the module requested in the config *)
List.iter
(fun m ->
Expand Down
1 change: 0 additions & 1 deletion ocaml/xcp-rrdd/bin/rrdd/xcp_rrdd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,6 @@ let _ =
debug "Reading configuration file .." ;
Xcp_service.configure2 ~name:Sys.argv.(0) ~version:Xapi_version.version ~doc
~options () ;
Xcp_service.maybe_daemonize () ;
debug "Starting the HTTP server .." ;
(* Eventually we should switch over to xcp_service to declare our services,
but since it doesn't support HTTP GET and PUT we keep the old code for now.
Expand Down
1 change: 0 additions & 1 deletion ocaml/xenopsd/lib/xenopsd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,6 @@ let main backend =
(* we need to catch this to make sure at_exit handlers are triggered. In
particuar, triggers for the bisect_ppx coverage profiling *)
let signal_handler n = debug "caught signal %d" n ; exit 0 in
Xcp_service.maybe_daemonize () ;
Sys.set_signal Sys.sigpipe Sys.Signal_ignore ;
Sys.set_signal Sys.sigterm (Sys.Signal_handle signal_handler) ;
Xenops_utils.set_fs_backend
Expand Down
8 changes: 1 addition & 7 deletions ocaml/xenopsd/xc/xenops_xc_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,7 @@ let check_domain0_uuid () =
]
in
let open Ezxenstore_core.Xenstore in
with_xs (fun xs -> List.iter (fun (k, v) -> xs.Xs.write k v) kvs) ;
if !Xcp_service.daemon then
(* before daemonizing we need to forget the xenstore client because the
background thread will be gone after the fork().
Note that this leaks a thread.
*)
forget_client ()
with_xs (fun xs -> List.iter (fun (k, v) -> xs.Xs.write k v) kvs)

let make_var_run_xen () =
Xapi_stdext_unix.Unixext.mkdir_rec Device_common.var_run_xen_path 0o0755
Expand Down
2 changes: 1 addition & 1 deletion quality-gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ mli-files () {
}

structural-equality () {
N=11
N=9
EQ=$(git grep -r --count ' == ' -- '**/*.ml' ':!ocaml/sdk-gen/**/*.ml' | cut -d ':' -f 2 | paste -sd+ - | bc)
if [ "$EQ" -eq "$N" ]; then
echo "OK counted $EQ usages of ' == '"
Expand Down
2 changes: 0 additions & 2 deletions scripts/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@
Description=Monitor CDROM of %I

[Service]
Type=forking
GuessMainPID=no
ExecStart=/opt/xensource/libexec/cdrommon /dev/xapi/cd/%I

0 comments on commit e90a98e

Please sign in to comment.