package corosync
OCaml Corosync binding
Install
Dune Dependency
Authors
Maintainers
Sources
corosync-0.0.1.tbz
sha256=c1cf8ae96757c0b9f91b7619dc0f6417782e0734404965667796098c0710fafd
sha512=b936be73cf049c5499e6eafef22caa459cf52553d0412f777213c810bae38bc77b55843edf671652115751279da66e834d4d9b7391e1d85aca4975ab4fd9626f
doc/src/corosync.tools/quorumtool.ml.html
Source file quorumtool.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
open Ctypes open Corosync_lib open Corotypes open CsError let ( >>= ) = Result.bind type name_format = AddressFormatName | AddressFormatIP module ViewList = struct let mu = Mutex.create () let g_view_list_entries = ref 0 type node_name = Name of string | Ips of Ipaddr.t list type view_list_entry = { vq_info: Votequorum.vinfo option ; name: node_name option (* either the hostname or the ipaddrs *) ; node_id: int } let g_view_list : view_list_entry list ref = ref [] let g_called = ref false let copy_view_list view_list view_list_entries = List.init view_list_entries Fun.id |> List.map (fun i -> let node_id = !@(view_list +@ i) |> Unsigned.UInt32.to_int in {vq_info= None; name= None; node_id} ) |> ( := ) g_view_list let get_name_by_format node_id = function | AddressFormatIP -> ( let open Cmap in with_handle @@ fun chandle -> get_prefix chandle "nodelist.node" >>= fun node_list -> List.find_opt (fun (_k, v) -> v = string_of_int node_id) node_list |> Option.fold ~none:(Error CsErrNotExist) ~some:(fun (name_key, _v) -> Scanf.sscanf name_key "nodelist.node.%d.nodeid" Fun.id |> Result.ok ) >>= fun index -> List.filter_map (fun (k, v) -> if Astring.String.is_prefix ~affix:(Printf.sprintf "nodelist.node.%d.ring" index) k then Some v else None ) node_list |> fun l -> (try List.map Ipaddr.of_string_exn l with Ipaddr.Parse_error _ -> []) |> function | [] -> Error CsErrExist | ipaddrs -> Ok (Ips ipaddrs) (* let open Cfg in cfg_get_node_addrs handle node_id >>= fun node_addrs -> Ok (List.map (fun {addr; _} -> addr) node_addrs |> String.concat ",") *) ) | AddressFormatName -> let open Cmap in with_handle @@ fun chandle -> get_prefix chandle "nodelist.node" >>= fun node_list -> List.find_opt (fun (_k, v) -> v = string_of_int node_id) node_list |> Option.fold ~none:(Error CsErrNotExist) ~some:(fun (name_key, _v) -> Scanf.sscanf name_key "nodelist.node.%d.nodeid" Fun.id |> Result.ok ) >>= fun id -> Printf.sprintf "nodelist.node.%d.name" id |> fun k -> List.assoc_opt k node_list |> Option.fold ~none:(Error CsErrExist) ~some:(fun name -> Ok (Name name) ) let resolve_view_list_names format = let open Cfg in Mutex.lock mu ; let new_view_list = List.map (fun {node_id; _} -> get_name_by_format node_id format >>= fun addr -> Ok {node_id; name= Some addr; vq_info= None} ) !g_view_list in match List.find_opt Result.is_error new_view_list with | Some e -> Result.get_error e |> Result.error | None -> Ok (List.map Result.get_ok new_view_list) >>= fun new_list -> g_view_list := new_list ; Ok () >>= fun () -> Mutex.unlock mu ; Ok () let ocaml_quorum_notify_fn _handle _quorate _ring_seq view_list_entries view_list = Mutex.lock mu ; g_called := true ; g_view_list_entries := Unsigned.UInt32.to_int view_list_entries ; copy_view_list view_list !g_view_list_entries ; Mutex.unlock mu (** A view_list contains the current members in the quorum. Call this function to retrieve it. Call [update_membership_info] to update the viewlist before retrieving view_list *) let get_view_list () = let r : view_list_entry list ref = ref [] in Mutex.lock mu ; r := !g_view_list ; Mutex.unlock mu ; !r let get_g_called () = let r = ref false in Mutex.lock mu ; r := !g_called ; Mutex.unlock mu ; !r let reset_g_called () = Mutex.lock mu ; g_called := false ; Mutex.unlock mu end let dispatch qhandle flag = ViewList.reset_g_called () ; let rec dispatch_aux qhandle flag = Quorum.quorum_dispatch qhandle flag |> CsError.to_result >>= fun () -> if ViewList.get_g_called () then Ok () else dispatch_aux qhandle flag in dispatch_aux qhandle flag (* The output of corosync-quorumtool can be separated into three sections: 1. Quorum information 2. Votequorum information 3. Membership information The second and third part are present only if votequorum(5) is enabled in corosync. *) let with_quorum_track f = let open Quorum in let qhandle = allocate quorum_handle_t Unsigned.UInt64.zero in let qtype = allocate uint32_t Unsigned.UInt32.zero in let qcb = make quorum_callbacks_t in setf qcb quorum_notify_fn ViewList.ocaml_quorum_notify_fn ; quorum_initialize qhandle (addr qcb) qtype |> CsError.to_result >>= fun () -> quorum_trackstart !@qhandle (Unsigned.UInt.of_int cs_track_current) |> CsError.to_result >>= fun () -> dispatch !@qhandle CsDispatchFlag.(CsDispatchOne |> to_int) >>= fun () -> let r = f () in quorum_trackstop !@qhandle |> CsError.to_result >>= fun () -> quorum_finalize !@qhandle |> to_result >>= fun () -> r let is_quorate () = Quorum.(with_handle @@ getquorate) let using_votequorum () = Cmapctl.get "quorum.provider" |> Result.fold ~ok:(String.equal "corosync_votequorum") ~error:(Fun.const false) let votequorum_info id = if using_votequorum () then Votequorum.(with_handle @@ fun handle -> get_info handle id) else Error CsErrNoVoteQuorum let my_votequorum_info () = Cfg.(with_handle cfg_local_get) >>= votequorum_info let quorum_members name_format = with_quorum_track @@ fun () -> let open ViewList in ViewList.resolve_view_list_names name_format >>= fun () -> ViewList.get_view_list () |> Result.ok >>= fun vl -> let vqinfo_l = List.map (fun {node_id; _} -> votequorum_info node_id) vl in ( match List.find_opt Result.is_error vqinfo_l with | Some e -> Result.get_error e |> Result.error | None -> Ok (List.map Result.get_ok vqinfo_l) ) >>= fun vqinfo_l -> List.map2 (fun vq_info vle -> {vle with vq_info= Some vq_info}) vqinfo_l vl |> Result.ok
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>