|
38 | 38 | #include "src/common/libutil/errprintf.h" |
39 | 39 | #include "src/common/librouter/rpc_track.h" |
40 | 40 | #include "ccan/str/str.h" |
| 41 | +#include "ccan/array_size/array_size.h" |
41 | 42 |
|
42 | 43 | #include "overlay.h" |
43 | 44 | #include "attr.h" |
@@ -185,6 +186,7 @@ struct overlay { |
185 | 186 | void *recv_arg; |
186 | 187 |
|
187 | 188 | struct flux_msglist *health_requests; |
| 189 | + struct idset *flub_rankpool; |
188 | 190 | }; |
189 | 191 |
|
190 | 192 | static void overlay_mcast_child (struct overlay *ov, flux_msg_t *msg); |
@@ -286,6 +288,10 @@ int overlay_set_topology (struct overlay *ov, struct topology *topo) |
286 | 288 |
|
287 | 289 | ov->size = topology_get_size (topo); |
288 | 290 | ov->rank = topology_get_rank (topo); |
| 291 | + if (ov->rank == 0) { |
| 292 | + if (!(ov->flub_rankpool = idset_create (ov->size, 0))) |
| 293 | + goto error; |
| 294 | + } |
289 | 295 | if (!cert_meta_get (ov->cert, "name")) { |
290 | 296 | char val[16]; |
291 | 297 | snprintf (val, sizeof (val), "%lu", (unsigned long)ov->rank); |
@@ -2073,11 +2079,142 @@ static int overlay_configure_topo (struct overlay *ov) |
2073 | 2079 | return 0; |
2074 | 2080 | } |
2075 | 2081 |
|
| 2082 | +static int overlay_flub_alloc (struct overlay *ov, int *rank) |
| 2083 | +{ |
| 2084 | + unsigned int id; |
| 2085 | + |
| 2086 | + if (!ov->flub_rankpool) { // created by overlay_set_topology() |
| 2087 | + errno = EINVAL; |
| 2088 | + return -1; |
| 2089 | + } |
| 2090 | + if ((id = idset_first (ov->flub_rankpool)) != IDSET_INVALID_ID) { |
| 2091 | + if (idset_clear (ov->flub_rankpool, id) < 0) |
| 2092 | + return -1; |
| 2093 | + *rank = (int)id; |
| 2094 | + return 0; |
| 2095 | + } |
| 2096 | + errno = ENOENT; |
| 2097 | + return -1; |
| 2098 | +} |
| 2099 | + |
| 2100 | +int overlay_flub_provision (struct overlay *ov, |
| 2101 | + uint32_t lo_rank, |
| 2102 | + uint32_t hi_rank, |
| 2103 | + bool available) |
| 2104 | +{ |
| 2105 | + if (!ov->flub_rankpool) { // created by overlay_set_topology() |
| 2106 | + errno = EINVAL; |
| 2107 | + return -1; |
| 2108 | + } |
| 2109 | + if (available) |
| 2110 | + return idset_range_set (ov->flub_rankpool, lo_rank, hi_rank); |
| 2111 | + return idset_range_clear (ov->flub_rankpool, lo_rank, hi_rank); |
| 2112 | +} |
| 2113 | + |
| 2114 | +static json_t *flub_dict_create (attr_t *attrs) |
| 2115 | +{ |
| 2116 | + const char *names[] = { "hostlist", "instance-level" }; |
| 2117 | + json_t *dict; |
| 2118 | + |
| 2119 | + if (!(dict = json_object ())) |
| 2120 | + goto nomem; |
| 2121 | + for (int i = 0; i < ARRAY_SIZE (names); i++) { |
| 2122 | + const char *val; |
| 2123 | + json_t *o; |
| 2124 | + if (attr_get (attrs, names[i], &val, NULL) < 0) |
| 2125 | + goto error; |
| 2126 | + if (!(o = json_string (val)) |
| 2127 | + || json_object_set_new (dict, names[i], o) < 0) { |
| 2128 | + json_decref (o); |
| 2129 | + goto nomem; |
| 2130 | + } |
| 2131 | + } |
| 2132 | + return dict; |
| 2133 | +nomem: |
| 2134 | + errno = ENOMEM; |
| 2135 | +error: |
| 2136 | + ERRNO_SAFE_WRAP (json_decref, dict); |
| 2137 | + return NULL; |
| 2138 | +} |
| 2139 | + |
| 2140 | +static void overlay_flub_getinfo_cb (flux_t *h, |
| 2141 | + flux_msg_handler_t *mh, |
| 2142 | + const flux_msg_t *msg, |
| 2143 | + void *arg) |
| 2144 | +{ |
| 2145 | + struct overlay *ov = arg; |
| 2146 | + const char *errmsg = NULL; |
| 2147 | + json_t *attrs = NULL; |
| 2148 | + int rank; |
| 2149 | + |
| 2150 | + if (flux_request_unpack (msg, NULL, "{}") < 0) |
| 2151 | + goto error; |
| 2152 | + if (overlay_flub_alloc (ov, &rank) < 0) { |
| 2153 | + errmsg = "there are no available ranks"; |
| 2154 | + goto error; |
| 2155 | + } |
| 2156 | + if (!(attrs = flub_dict_create (ov->attrs))) |
| 2157 | + goto error; |
| 2158 | + if (flux_respond_pack (h, |
| 2159 | + msg, |
| 2160 | + "{s:i s:i s:O}", |
| 2161 | + "rank", rank, |
| 2162 | + "size", ov->size, |
| 2163 | + "attrs", attrs) < 0) |
| 2164 | + flux_log_error (h, "error responding to overlay.flub-getinfo request"); |
| 2165 | + json_decref (attrs); |
| 2166 | + return; |
| 2167 | +error: |
| 2168 | + if (flux_respond_error (h, msg, errno, errmsg) < 0) |
| 2169 | + flux_log_error (h, "error responding to overlay.flub-getinfo request"); |
| 2170 | + json_decref (attrs); |
| 2171 | +} |
| 2172 | + |
| 2173 | +static void overlay_flub_kex_cb (flux_t *h, |
| 2174 | + flux_msg_handler_t *mh, |
| 2175 | + const flux_msg_t *msg, |
| 2176 | + void *arg) |
| 2177 | +{ |
| 2178 | + struct overlay *ov = arg; |
| 2179 | + const char *errmsg = NULL; |
| 2180 | + const char *name; |
| 2181 | + const char *pubkey; |
| 2182 | + |
| 2183 | + if (flux_request_unpack (msg, |
| 2184 | + NULL, |
| 2185 | + "{s:s s:s}", |
| 2186 | + "name", &name, |
| 2187 | + "pubkey", &pubkey) < 0) |
| 2188 | + goto error; |
| 2189 | + if (ov->child_count == 0) { |
| 2190 | + errmsg = "this broker cannot have children"; |
| 2191 | + errno = EINVAL; |
| 2192 | + goto error; |
| 2193 | + } |
| 2194 | + if (overlay_authorize (ov, name, pubkey) < 0) { |
| 2195 | + errmsg = "failed to authorize public key"; |
| 2196 | + goto error; |
| 2197 | + } |
| 2198 | + if (flux_respond_pack (h, |
| 2199 | + msg, |
| 2200 | + "{s:s s:s s:s}", |
| 2201 | + "pubkey", overlay_cert_pubkey (ov), |
| 2202 | + "name", overlay_cert_name (ov), |
| 2203 | + "uri", overlay_get_bind_uri (ov)) < 0) |
| 2204 | + flux_log_error (h, "error responding to overlay.flub-kex request"); |
| 2205 | + return; |
| 2206 | +error: |
| 2207 | + if (flux_respond_error (h, msg, errno, errmsg) < 0) |
| 2208 | + flux_log_error (h, "error responding to overlay.flub-kex request"); |
| 2209 | +} |
| 2210 | + |
2076 | 2211 | void overlay_destroy (struct overlay *ov) |
2077 | 2212 | { |
2078 | 2213 | if (ov) { |
2079 | 2214 | int saved_errno = errno; |
2080 | 2215 |
|
| 2216 | + idset_destroy (ov->flub_rankpool); |
| 2217 | + |
2081 | 2218 | flux_msglist_destroy (ov->health_requests); |
2082 | 2219 |
|
2083 | 2220 | cert_destroy (ov->cert); |
@@ -2123,6 +2260,18 @@ void overlay_destroy (struct overlay *ov) |
2123 | 2260 | } |
2124 | 2261 |
|
2125 | 2262 | static const struct flux_msg_handler_spec htab[] = { |
| 2263 | + { |
| 2264 | + FLUX_MSGTYPE_REQUEST, |
| 2265 | + "overlay.flub-kex", |
| 2266 | + overlay_flub_kex_cb, |
| 2267 | + 0, |
| 2268 | + }, |
| 2269 | + { |
| 2270 | + FLUX_MSGTYPE_REQUEST, |
| 2271 | + "overlay.flub-getinfo", |
| 2272 | + overlay_flub_getinfo_cb, |
| 2273 | + 0, |
| 2274 | + }, |
2126 | 2275 | { |
2127 | 2276 | FLUX_MSGTYPE_REQUEST, |
2128 | 2277 | "overlay.stats-get", |
|
0 commit comments