|
33 | 33 | #include "src/common/librouter/rpc_track.h" |
34 | 34 | #include "src/common/libccan/ccan/ptrint/ptrint.h" |
35 | 35 | #include "src/common/libyuarel/yuarel.h" |
| 36 | +#include "ccan/array_size/array_size.h" |
36 | 37 |
|
37 | 38 | #include "overlay.h" |
38 | 39 | #include "attr.h" |
@@ -178,6 +179,7 @@ struct overlay { |
178 | 179 | void *recv_arg; |
179 | 180 |
|
180 | 181 | struct flux_msglist *health_requests; |
| 182 | + struct idset *flub_rankpool; |
181 | 183 | }; |
182 | 184 |
|
183 | 185 | static void overlay_mcast_child (struct overlay *ov, const flux_msg_t *msg); |
@@ -279,6 +281,8 @@ int overlay_set_topology (struct overlay *ov, struct topology *topo) |
279 | 281 |
|
280 | 282 | ov->size = topology_get_size (topo); |
281 | 283 | ov->rank = topology_get_rank (topo); |
| 284 | + if (!(ov->flub_rankpool = idset_create (ov->size, 0))) |
| 285 | + goto error; |
282 | 286 | if (!zcert_meta (ov->cert, "name")) { |
283 | 287 | char buf[16]; |
284 | 288 | snprintf (buf, sizeof (buf), "%lu", (unsigned long)ov->rank); |
@@ -2061,11 +2065,142 @@ static int overlay_configure_topo (struct overlay *ov) |
2061 | 2065 | return 0; |
2062 | 2066 | } |
2063 | 2067 |
|
| 2068 | +static int overlay_flub_alloc (struct overlay *ov, int *rank) |
| 2069 | +{ |
| 2070 | + unsigned int id; |
| 2071 | + |
| 2072 | + if (!ov->flub_rankpool) { // created by overlay_set_topology() |
| 2073 | + errno = EINVAL; |
| 2074 | + return -1; |
| 2075 | + } |
| 2076 | + if ((id = idset_first (ov->flub_rankpool)) != IDSET_INVALID_ID) { |
| 2077 | + if (idset_clear (ov->flub_rankpool, id) < 0) |
| 2078 | + return -1; |
| 2079 | + *rank = (int)id; |
| 2080 | + return 0; |
| 2081 | + } |
| 2082 | + errno = ENOENT; |
| 2083 | + return -1; |
| 2084 | +} |
| 2085 | + |
| 2086 | +int overlay_flub_provision (struct overlay *ov, |
| 2087 | + uint32_t lo_rank, |
| 2088 | + uint32_t hi_rank, |
| 2089 | + bool available) |
| 2090 | +{ |
| 2091 | + if (!ov->flub_rankpool) { // created by overlay_set_topology() |
| 2092 | + errno = EINVAL; |
| 2093 | + return -1; |
| 2094 | + } |
| 2095 | + if (available) |
| 2096 | + return idset_range_set (ov->flub_rankpool, lo_rank, hi_rank); |
| 2097 | + return idset_range_clear (ov->flub_rankpool, lo_rank, hi_rank); |
| 2098 | +} |
| 2099 | + |
| 2100 | +static json_t *flub_dict_create (attr_t *attrs) |
| 2101 | +{ |
| 2102 | + const char *names[] = { "hostlist", "instance-level" }; |
| 2103 | + json_t *dict; |
| 2104 | + |
| 2105 | + if (!(dict = json_object ())) |
| 2106 | + goto nomem; |
| 2107 | + for (int i = 0; i < ARRAY_SIZE (names); i++) { |
| 2108 | + const char *val; |
| 2109 | + json_t *o; |
| 2110 | + if (attr_get (attrs, names[i], &val, NULL) < 0) |
| 2111 | + goto error; |
| 2112 | + if (!(o = json_string (val)) |
| 2113 | + || json_object_set_new (dict, names[i], o) < 0) { |
| 2114 | + json_decref (o); |
| 2115 | + goto nomem; |
| 2116 | + } |
| 2117 | + } |
| 2118 | + return dict; |
| 2119 | +nomem: |
| 2120 | + errno = ENOMEM; |
| 2121 | +error: |
| 2122 | + ERRNO_SAFE_WRAP (json_decref, dict); |
| 2123 | + return NULL; |
| 2124 | +} |
| 2125 | + |
| 2126 | +static void overlay_flub_getinfo_cb (flux_t *h, |
| 2127 | + flux_msg_handler_t *mh, |
| 2128 | + const flux_msg_t *msg, |
| 2129 | + void *arg) |
| 2130 | +{ |
| 2131 | + struct overlay *ov = arg; |
| 2132 | + const char *errmsg = NULL; |
| 2133 | + json_t *attrs = NULL; |
| 2134 | + int rank; |
| 2135 | + |
| 2136 | + if (flux_request_unpack (msg, NULL, "{}") < 0) |
| 2137 | + goto error; |
| 2138 | + if (overlay_flub_alloc (ov, &rank) < 0) { |
| 2139 | + errmsg = "there are no available ranks"; |
| 2140 | + goto error; |
| 2141 | + } |
| 2142 | + if (!(attrs = flub_dict_create (ov->attrs))) |
| 2143 | + goto error; |
| 2144 | + if (flux_respond_pack (h, |
| 2145 | + msg, |
| 2146 | + "{s:i s:i s:O}", |
| 2147 | + "rank", rank, |
| 2148 | + "size", ov->size, |
| 2149 | + "attrs", attrs) < 0) |
| 2150 | + flux_log_error (h, "error responding to overlay.flub-getinfo request"); |
| 2151 | + json_decref (attrs); |
| 2152 | + return; |
| 2153 | +error: |
| 2154 | + if (flux_respond_error (h, msg, errno, errmsg) < 0) |
| 2155 | + flux_log_error (h, "error responding to overlay.flub-getinfo request"); |
| 2156 | + json_decref (attrs); |
| 2157 | +} |
| 2158 | + |
| 2159 | +static void overlay_flub_kex_cb (flux_t *h, |
| 2160 | + flux_msg_handler_t *mh, |
| 2161 | + const flux_msg_t *msg, |
| 2162 | + void *arg) |
| 2163 | +{ |
| 2164 | + struct overlay *ov = arg; |
| 2165 | + const char *errmsg = NULL; |
| 2166 | + const char *name; |
| 2167 | + const char *pubkey; |
| 2168 | + |
| 2169 | + if (flux_request_unpack (msg, |
| 2170 | + NULL, |
| 2171 | + "{s:s s:s}", |
| 2172 | + "name", &name, |
| 2173 | + "pubkey", &pubkey) < 0) |
| 2174 | + goto error; |
| 2175 | + if (ov->child_count == 0) { |
| 2176 | + errmsg = "this broker cannot have children"; |
| 2177 | + errno = EINVAL; |
| 2178 | + goto error; |
| 2179 | + } |
| 2180 | + if (overlay_authorize (ov, name, pubkey) < 0) { |
| 2181 | + errmsg = "failed to authorize public key"; |
| 2182 | + goto error; |
| 2183 | + } |
| 2184 | + if (flux_respond_pack (h, |
| 2185 | + msg, |
| 2186 | + "{s:s s:s s:s}", |
| 2187 | + "pubkey", overlay_cert_pubkey (ov), |
| 2188 | + "name", overlay_cert_name (ov), |
| 2189 | + "uri", overlay_get_bind_uri (ov)) < 0) |
| 2190 | + flux_log_error (h, "error responding to overlay.flub-kex request"); |
| 2191 | + return; |
| 2192 | +error: |
| 2193 | + if (flux_respond_error (h, msg, errno, errmsg) < 0) |
| 2194 | + flux_log_error (h, "error responding to overlay.flub-kex request"); |
| 2195 | +} |
| 2196 | + |
2064 | 2197 | void overlay_destroy (struct overlay *ov) |
2065 | 2198 | { |
2066 | 2199 | if (ov) { |
2067 | 2200 | int saved_errno = errno; |
2068 | 2201 |
|
| 2202 | + idset_destroy (ov->flub_rankpool); |
| 2203 | + |
2069 | 2204 | flux_msglist_destroy (ov->health_requests); |
2070 | 2205 |
|
2071 | 2206 | zcert_destroy (&ov->cert); |
@@ -2109,6 +2244,18 @@ void overlay_destroy (struct overlay *ov) |
2109 | 2244 | } |
2110 | 2245 |
|
2111 | 2246 | static const struct flux_msg_handler_spec htab[] = { |
| 2247 | + { |
| 2248 | + FLUX_MSGTYPE_REQUEST, |
| 2249 | + "overlay.flub-kex", |
| 2250 | + overlay_flub_kex_cb, |
| 2251 | + 0, |
| 2252 | + }, |
| 2253 | + { |
| 2254 | + FLUX_MSGTYPE_REQUEST, |
| 2255 | + "overlay.flub-getinfo", |
| 2256 | + overlay_flub_getinfo_cb, |
| 2257 | + 0, |
| 2258 | + }, |
2112 | 2259 | { |
2113 | 2260 | FLUX_MSGTYPE_REQUEST, |
2114 | 2261 | "overlay.stats-get", |
|
0 commit comments