|
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); |
@@ -2061,11 +2063,140 @@ static int overlay_configure_topo (struct overlay *ov) |
2061 | 2063 | return 0; |
2062 | 2064 | } |
2063 | 2065 |
|
| 2066 | +static int overlay_flub_alloc (struct overlay *ov, int *rank) |
| 2067 | +{ |
| 2068 | + unsigned int id; |
| 2069 | + |
| 2070 | + if (ov->flub_rankpool) { |
| 2071 | + if ((id = idset_first (ov->flub_rankpool)) != IDSET_INVALID_ID) { |
| 2072 | + if (idset_clear (ov->flub_rankpool, id) < 0) |
| 2073 | + return -1; |
| 2074 | + *rank = (int)id; |
| 2075 | + return 0; |
| 2076 | + } |
| 2077 | + } |
| 2078 | + errno = ENOENT; |
| 2079 | + return -1; |
| 2080 | +} |
| 2081 | + |
| 2082 | +int overlay_flub_provision (struct overlay *ov, int start_rank) |
| 2083 | +{ |
| 2084 | + struct idset *ids; |
| 2085 | + |
| 2086 | + if (!(ids = idset_create (ov->size, 0)) |
| 2087 | + || idset_range_set (ids, start_rank, ov->size - 1) < 0) { |
| 2088 | + idset_destroy (ids); |
| 2089 | + return -1; |
| 2090 | + } |
| 2091 | + idset_destroy (ov->flub_rankpool); |
| 2092 | + ov->flub_rankpool = ids; |
| 2093 | + return 0; |
| 2094 | +} |
| 2095 | + |
| 2096 | +static json_t *flub_dict_create (attr_t *attrs) |
| 2097 | +{ |
| 2098 | + const char *names[] = { "hostlist", "instance-level" }; |
| 2099 | + json_t *dict; |
| 2100 | + |
| 2101 | + if (!(dict = json_object ())) |
| 2102 | + goto nomem; |
| 2103 | + for (int i = 0; i < ARRAY_SIZE (names); i++) { |
| 2104 | + const char *val; |
| 2105 | + json_t *o; |
| 2106 | + if (attr_get (attrs, names[i], &val, NULL) < 0) |
| 2107 | + goto error; |
| 2108 | + if (!(o = json_string (val)) |
| 2109 | + || json_object_set_new (dict, names[i], o) < 0) { |
| 2110 | + json_decref (o); |
| 2111 | + goto nomem; |
| 2112 | + } |
| 2113 | + } |
| 2114 | + return dict; |
| 2115 | +nomem: |
| 2116 | + errno = ENOMEM; |
| 2117 | +error: |
| 2118 | + ERRNO_SAFE_WRAP (json_decref, dict); |
| 2119 | + return NULL; |
| 2120 | +} |
| 2121 | + |
| 2122 | +static void overlay_flub_getinfo_cb (flux_t *h, |
| 2123 | + flux_msg_handler_t *mh, |
| 2124 | + const flux_msg_t *msg, |
| 2125 | + void *arg) |
| 2126 | +{ |
| 2127 | + struct overlay *ov = arg; |
| 2128 | + const char *errmsg = NULL; |
| 2129 | + json_t *attrs = NULL; |
| 2130 | + int rank; |
| 2131 | + |
| 2132 | + if (flux_request_unpack (msg, NULL, "{}") < 0) |
| 2133 | + goto error; |
| 2134 | + if (overlay_flub_alloc (ov, &rank) < 0) { |
| 2135 | + errmsg = "there are no available ranks"; |
| 2136 | + goto error; |
| 2137 | + } |
| 2138 | + if (!(attrs = flub_dict_create (ov->attrs))) |
| 2139 | + goto error; |
| 2140 | + if (flux_respond_pack (h, |
| 2141 | + msg, |
| 2142 | + "{s:i s:i s:O}", |
| 2143 | + "rank", rank, |
| 2144 | + "size", ov->size, |
| 2145 | + "attrs", attrs) < 0) |
| 2146 | + flux_log_error (h, "error responding to overlay.flub-getinfo request"); |
| 2147 | + json_decref (attrs); |
| 2148 | + return; |
| 2149 | +error: |
| 2150 | + if (flux_respond_error (h, msg, errno, errmsg) < 0) |
| 2151 | + flux_log_error (h, "error responding to overlay.flub-getinfo request"); |
| 2152 | + json_decref (attrs); |
| 2153 | +} |
| 2154 | + |
| 2155 | +static void overlay_flub_kex_cb (flux_t *h, |
| 2156 | + flux_msg_handler_t *mh, |
| 2157 | + const flux_msg_t *msg, |
| 2158 | + void *arg) |
| 2159 | +{ |
| 2160 | + struct overlay *ov = arg; |
| 2161 | + const char *errmsg = NULL; |
| 2162 | + const char *name; |
| 2163 | + const char *pubkey; |
| 2164 | + |
| 2165 | + if (flux_request_unpack (msg, |
| 2166 | + NULL, |
| 2167 | + "{s:s s:s}", |
| 2168 | + "name", &name, |
| 2169 | + "pubkey", &pubkey) < 0) |
| 2170 | + goto error; |
| 2171 | + if (ov->child_count == 0) { |
| 2172 | + errmsg = "this broker cannot have children"; |
| 2173 | + errno = EINVAL; |
| 2174 | + goto error; |
| 2175 | + } |
| 2176 | + if (overlay_authorize (ov, name, pubkey) < 0) { |
| 2177 | + errmsg = "failed to authorize public key"; |
| 2178 | + goto error; |
| 2179 | + } |
| 2180 | + if (flux_respond_pack (h, |
| 2181 | + msg, |
| 2182 | + "{s:s s:s s:s}", |
| 2183 | + "pubkey", overlay_cert_pubkey (ov), |
| 2184 | + "name", overlay_cert_name (ov), |
| 2185 | + "uri", overlay_get_bind_uri (ov)) < 0) |
| 2186 | + flux_log_error (h, "error responding to overlay.flub-kex request"); |
| 2187 | + return; |
| 2188 | +error: |
| 2189 | + if (flux_respond_error (h, msg, errno, errmsg) < 0) |
| 2190 | + flux_log_error (h, "error responding to overlay.flub-kex request"); |
| 2191 | +} |
| 2192 | + |
2064 | 2193 | void overlay_destroy (struct overlay *ov) |
2065 | 2194 | { |
2066 | 2195 | if (ov) { |
2067 | 2196 | int saved_errno = errno; |
2068 | 2197 |
|
| 2198 | + idset_destroy (ov->flub_rankpool); |
| 2199 | + |
2069 | 2200 | flux_msglist_destroy (ov->health_requests); |
2070 | 2201 |
|
2071 | 2202 | zcert_destroy (&ov->cert); |
@@ -2109,6 +2240,18 @@ void overlay_destroy (struct overlay *ov) |
2109 | 2240 | } |
2110 | 2241 |
|
2111 | 2242 | static const struct flux_msg_handler_spec htab[] = { |
| 2243 | + { |
| 2244 | + FLUX_MSGTYPE_REQUEST, |
| 2245 | + "overlay.flub-kex", |
| 2246 | + overlay_flub_kex_cb, |
| 2247 | + 0, |
| 2248 | + }, |
| 2249 | + { |
| 2250 | + FLUX_MSGTYPE_REQUEST, |
| 2251 | + "overlay.flub-getinfo", |
| 2252 | + overlay_flub_getinfo_cb, |
| 2253 | + 0, |
| 2254 | + }, |
2112 | 2255 | { |
2113 | 2256 | FLUX_MSGTYPE_REQUEST, |
2114 | 2257 | "overlay.stats-get", |
|
0 commit comments