diff --git a/albatross.opam b/albatross.opam index 9a63a9b..4e71ed4 100644 --- a/albatross.opam +++ b/albatross.opam @@ -9,6 +9,7 @@ license: "ISC" depends: [ "ocaml" {>= "4.08.0"} "dune" + "dune-configurator" "lwt" {>= "3.0.0"} "ipaddr" {>= "4.0.0"} "hex" @@ -37,4 +38,8 @@ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] ] +depexts: [ + ["libnl-3-dev" "libnl-route-3-dev"] {os-family = "debian"} + ["libnl3" "libnl3-devel"] {os-family = "centos"} +] synopsis: "Albatross - orchestrate and manage MirageOS unikernels with Solo5" diff --git a/stats/albatross_stats_stubs.c b/stats/albatross_stats_stubs.c index c75a462..cbe22df 100644 --- a/stats/albatross_stats_stubs.c +++ b/stats/albatross_stats_stubs.c @@ -211,7 +211,100 @@ CAMLprim value vmmanage_sysctl_ifdata (value num) { CAMLreturn(res); } -#else /* FreeBSD */ +#elif __linux__ /* FreeBSD */ +#include +#include +#include + +#define get_stat(link, stat) rtnl_link_get_stat(link, RTNL_LINK_##stat) + +CAMLprim value vmmanage_sysctl_ifcount(value unit) { + CAMLparam1(unit); + int err; + struct nl_sock *nl_sock; + struct nl_cache *link_cache; + + nl_sock = nl_socket_alloc(); + if (nl_sock == 0) + uerror("nl_socket_alloc", Nothing); + err = nl_connect(nl_sock, NETLINK_ROUTE); + if (err < 0) + uerror("nl_connect", Nothing); + err = rtnl_link_alloc_cache(nl_sock, AF_UNSPEC, &link_cache); + if (err < 0) + uerror("rtnl_link_alloc_cache", Nothing); + + CAMLreturn(Val_long(nl_cache_nitems(link_cache))); +} + +CAMLprim value vmmanage_sysctl_ifdata(value num) { + CAMLparam1(num); + CAMLlocal1(res); + int err; + struct nl_sock *nl_sock; + struct nl_cache *link_cache; + struct rtnl_link *link; + + nl_sock = nl_socket_alloc(); + if (nl_sock == 0) + uerror("nl_socket_alloc", Nothing); + err = nl_connect(nl_sock, NETLINK_ROUTE); + if (err < 0) + uerror("nl_connect", Nothing); + err = rtnl_link_alloc_cache(nl_sock, AF_UNSPEC, &link_cache); + if (err < 0) + uerror("rtnl_link_alloc_cache", Nothing); + link = rtnl_link_get(link_cache, Int_val(num)); + if (link == NULL) + uerror("rtnl_link_get", Nothing); + res = caml_alloc(18, 0); + Store_field(res, 0, caml_copy_string(rtnl_link_get_name(link))); + Store_field(res, 1, Val32(rtnl_link_get_flags(link))); + Store_field(res, 2, Val32(0)); /* send_length */ + Store_field(res, 3, Val32(0)); /* max_send_length */ + Store_field(res, 4, Val32(0)); /* send_drops */ + Store_field(res, 5, Val32(rtnl_link_get_mtu(link))); + Store_field(res, 6, Val64(0)); /* baudrate */ + Store_field(res, 7, Val64(get_stat(link, RX_PACKETS))); + Store_field(res, 8, Val64(get_stat(link, RX_ERRORS))); + Store_field(res, 9, Val64(get_stat(link, TX_PACKETS))); + Store_field(res, 10, Val64(get_stat(link, TX_ERRORS))); + Store_field(res, 11, Val64(get_stat(link, COLLISIONS))); + Store_field(res, 12, Val64(get_stat(link, RX_BYTES))); + Store_field(res, 13, Val64(get_stat(link, TX_BYTES))); + Store_field(res, 14, Val64(get_stat(link, MULTICAST))); + Store_field(res, 15, Val64(0)); + Store_field(res, 16, Val64(get_stat(link, RX_DROPPED))); + Store_field(res, 17, Val64(get_stat(link, TX_DROPPED))); + CAMLreturn(res); +} + +CAMLprim value vmmanage_sysctl_kinfo_proc (value pid_r) { + CAMLparam1(pid_r); + uerror("sysctl_kinfo_proc", Nothing); +} + +CAMLprim value vmmanage_vmmapi_open (value name) { + CAMLparam1(name); + uerror("vmmapi_open", Nothing); +} + +CAMLprim value vmmanage_vmmapi_close (value name) { + CAMLparam1(name); + uerror("vmmapi_close", Nothing); +} + +CAMLprim value vmmanage_vmmapi_stats (value name) { + CAMLparam1(name); + uerror("vmmapi_stats", Nothing); +} + +CAMLprim value vmmanage_vmmapi_statnames (value name) { + CAMLparam1(name); + uerror("vmmapi_statnames", Nothing); +} + +#else /* Linux */ /* stub symbols for OS currently not supported */ diff --git a/stats/config/discover.ml b/stats/config/discover.ml new file mode 100644 index 0000000..51d0ca6 --- /dev/null +++ b/stats/config/discover.ml @@ -0,0 +1,39 @@ +module C = Configurator.V1 + +let write_sexp (conf : C.Pkg_config.package_conf) = + C.Flags.write_sexp "c_flags.sexp" conf.cflags; + C.Flags.write_sexp "c_library_flags.sexp" conf.libs + +let pkg_config_combine ~default deps = + let deps = + List.map (Result.fold ~ok:(fun x -> x) ~error:(fun e -> C.die "pkg-config: %s" e)) + deps in + List.fold_left (fun conf dep -> + C.Pkg_config.{ libs = conf.libs @ dep.libs; + cflags = conf.cflags @ dep.cflags }) + default deps + +let freebsd _c = + let conf = { C.Pkg_config.libs = ["-lvmmapi"]; cflags = [] } in + write_sexp conf + +let linux c = + (* FIXME: cflags -I *) + let default = { C.Pkg_config.libs = ["-lnl-3"; "-lnl-route-3"]; cflags = [] } in + let conf = + match C.Pkg_config.get c with + | None -> default + | Some pc -> + pkg_config_combine ~default [ + C.Pkg_config.query_expr_err pc ~package:"libnl-3.0" ~expr:"libnl-3.0"; + C.Pkg_config.query_expr_err pc ~package:"libnl-route-3.0" ~expr:"libnl-route-3.0"; + ] + in + write_sexp conf + +let () = + C.main ~name:"libnl-3-pkg-config" (fun c -> + match C.ocaml_config_var_exn c "system" with + | "freebsd" -> freebsd c + | "linux" -> linux c + | os -> failwith ("Unsupported platform: "^os)) diff --git a/stats/config/dune b/stats/config/dune new file mode 100644 index 0000000..21a5f9a --- /dev/null +++ b/stats/config/dune @@ -0,0 +1,3 @@ +(executable + (name discover) + (libraries dune.configurator)) diff --git a/stats/dune b/stats/dune index 15cbaca..6dafbbb 100644 --- a/stats/dune +++ b/stats/dune @@ -1,15 +1,11 @@ -(* -*- tuareg -*- *) - -let freebsd = try Sys.command "uname -s | grep -c FreeBSD > /dev/null" = 0 with _ -> false - -let () = - Jbuild_plugin.V1.send @@ Printf.sprintf {| (library (name albatross_stats) (public_name albatross.stats) (libraries albatross) (wrapped false) (c_names albatross_stats_stubs) + (c_flags (:include c_flags.sexp)) + (c_library_flags (:include c_library_flags.sexp)) (modules albatross_stats_pure)) (executable @@ -17,7 +13,6 @@ let () = (public_name albatross-stats) (package albatross) (modules albatross_stats) - %s (libraries albatross.cli albatross.stats albatross)) (executable @@ -25,9 +20,8 @@ let () = (public_name albatross-stat-client) (package albatross) (modules albatross_stat_client) - %s (libraries albatross.cli albatross.stats albatross)) - |} - (if freebsd then "(link_flags (-ccopt \"-lvmmapi\"))" else "") - (if freebsd then "(link_flags (-ccopt \"-lvmmapi\"))" else "") +(rule + (targets c_flags.sexp c_library_flags.sexp) + (action (run ./config/discover.exe)))