|
31 | 31 | #include <unordered_map>
|
32 | 32 | #include <unordered_set>
|
33 | 33 |
|
| 34 | +#ifdef LLAMA_CPP_SYSTEMD_SUPPORT |
| 35 | +# include <sys/socket.h> |
| 36 | +# include <sys/stat.h> |
| 37 | +# include <systemd/sd-daemon.h> |
| 38 | +#endif // LLAMA_CPP_SYSTEMD_SUPPORT |
| 39 | + |
34 | 40 | using json = nlohmann::ordered_json;
|
35 | 41 |
|
36 | 42 | constexpr int HTTP_POLLING_SECONDS = 1;
|
@@ -4110,6 +4116,38 @@ inline void signal_handler(int signal) {
|
4110 | 4116 | shutdown_handler(signal);
|
4111 | 4117 | }
|
4112 | 4118 |
|
| 4119 | +#ifdef LLAMA_CPP_SYSTEMD_SUPPORT |
| 4120 | +// Subclass of httplib::Server that adds systemd socket activation support on systems |
| 4121 | +// where that's available. |
| 4122 | +class SystemdServer : public httplib::Server { |
| 4123 | + public: |
| 4124 | + bool setup_sd_socket() { |
| 4125 | + int n = sd_listen_fds(0); |
| 4126 | + if (n != 1) { |
| 4127 | + LOG_ERR("%s: sd_listen_fds() returned %d\n", __func__, n); |
| 4128 | + return false; |
| 4129 | + } |
| 4130 | + |
| 4131 | + int fd = SD_LISTEN_FDS_START; |
| 4132 | + struct stat statbuf; |
| 4133 | + if (fstat(fd, &statbuf) == -1 || !S_ISSOCK(statbuf.st_mode)) { |
| 4134 | + LOG_ERR("%s: fstat() failed or fd is not a socket\n", __func__); |
| 4135 | + return false; |
| 4136 | + } |
| 4137 | + |
| 4138 | + LOG_INF("%s: using systemd socket fd %d\n", __func__, fd); |
| 4139 | + svr_sock_ = fd; |
| 4140 | + return true; |
| 4141 | + } |
| 4142 | +}; |
| 4143 | +#endif // LLAMA_CPP_SYSTEMD_SUPPORT |
| 4144 | + |
| 4145 | +#ifdef LLAMA_CPP_SYSTEMD_SUPPORT |
| 4146 | +# define NEW_SERVER (new SystemdServer()) |
| 4147 | +#else |
| 4148 | +# define NEW_SERVER (new httplib::Server()) |
| 4149 | +#endif // LLAMA_CPP_SYSTEMD_SUPPORT |
| 4150 | + |
4113 | 4151 | int main(int argc, char ** argv) {
|
4114 | 4152 | // own arguments required by this example
|
4115 | 4153 | common_params params;
|
@@ -4139,14 +4177,14 @@ int main(int argc, char ** argv) {
|
4139 | 4177 | svr.reset(new httplib::SSLServer(params.ssl_file_cert.c_str(), params.ssl_file_key.c_str()));
|
4140 | 4178 | } else {
|
4141 | 4179 | LOG_INF("Running without SSL\n");
|
4142 |
| - svr.reset(new httplib::Server()); |
| 4180 | + svr.reset(NEW_SERVER); |
4143 | 4181 | }
|
4144 | 4182 | #else
|
4145 | 4183 | if (params.ssl_file_key != "" && params.ssl_file_cert != "") {
|
4146 | 4184 | LOG_ERR("Server is built without SSL support\n");
|
4147 | 4185 | return 1;
|
4148 | 4186 | }
|
4149 |
| - svr.reset(new httplib::Server()); |
| 4187 | + svr.reset(NEW_SERVER); |
4150 | 4188 | #endif
|
4151 | 4189 |
|
4152 | 4190 | std::atomic<server_state> state{ SERVER_STATE_LOADING_MODEL };
|
@@ -5342,23 +5380,37 @@ int main(int argc, char ** argv) {
|
5342 | 5380 |
|
5343 | 5381 | bool was_bound = false;
|
5344 | 5382 | bool is_sock = false;
|
5345 |
| - if (string_ends_with(std::string(params.hostname), ".sock")) { |
5346 |
| - is_sock = true; |
5347 |
| - LOG_INF("%s: setting address family to AF_UNIX\n", __func__); |
5348 |
| - svr->set_address_family(AF_UNIX); |
5349 |
| - // bind_to_port requires a second arg, any value other than 0 should |
5350 |
| - // simply get ignored |
5351 |
| - was_bound = svr->bind_to_port(params.hostname, 8080); |
5352 |
| - } else { |
5353 |
| - LOG_INF("%s: binding port with default address family\n", __func__); |
5354 |
| - // bind HTTP listen port |
5355 |
| - if (params.port == 0) { |
5356 |
| - int bound_port = svr->bind_to_any_port(params.hostname); |
5357 |
| - if ((was_bound = (bound_port >= 0))) { |
5358 |
| - params.port = bound_port; |
5359 |
| - } |
| 5383 | + |
| 5384 | +#ifdef LLAMA_CPP_SYSTEMD_SUPPORT |
| 5385 | + bool using_sd_socket = false; |
| 5386 | + if (params.use_systemd) { |
| 5387 | + was_bound = static_cast<SystemdServer *>(svr.get())->setup_sd_socket(); |
| 5388 | + using_sd_socket = was_bound; |
| 5389 | + if (!was_bound) { |
| 5390 | + LOG_INF("%s: couldn't set up systemd socket; falling back to opening host:port socket\n", __func__); |
| 5391 | + } |
| 5392 | + } |
| 5393 | +#endif // LLAMA_CPP_SYSTEMD_SUPPORT |
| 5394 | + |
| 5395 | + if (!was_bound) { |
| 5396 | + if (string_ends_with(std::string(params.hostname), ".sock")) { |
| 5397 | + is_sock = true; |
| 5398 | + LOG_INF("%s: setting address family to AF_UNIX\n", __func__); |
| 5399 | + svr->set_address_family(AF_UNIX); |
| 5400 | + // bind_to_port requires a second arg, any value other than 0 should |
| 5401 | + // simply get ignored |
| 5402 | + was_bound = svr->bind_to_port(params.hostname, 8080); |
5360 | 5403 | } else {
|
5361 |
| - was_bound = svr->bind_to_port(params.hostname, params.port); |
| 5404 | + LOG_INF("%s: binding port with default address family\n", __func__); |
| 5405 | + // bind HTTP listen port |
| 5406 | + if (params.port == 0) { |
| 5407 | + int bound_port = svr->bind_to_any_port(params.hostname); |
| 5408 | + if ((was_bound = (bound_port >= 0))) { |
| 5409 | + params.port = bound_port; |
| 5410 | + } |
| 5411 | + } else { |
| 5412 | + was_bound = svr->bind_to_port(params.hostname, params.port); |
| 5413 | + } |
5362 | 5414 | }
|
5363 | 5415 | }
|
5364 | 5416 |
|
@@ -5389,6 +5441,12 @@ int main(int argc, char ** argv) {
|
5389 | 5441 | ctx_server.init();
|
5390 | 5442 | state.store(SERVER_STATE_READY);
|
5391 | 5443 |
|
| 5444 | +#ifdef LLAMA_CPP_SYSTEMD_SUPPORT |
| 5445 | + if (params.use_systemd) { |
| 5446 | + sd_notify(0, "READY=1"); |
| 5447 | + } |
| 5448 | +#endif |
| 5449 | + |
5392 | 5450 | LOG_INF("%s: model loaded\n", __func__);
|
5393 | 5451 |
|
5394 | 5452 | // print sample chat example to make it clear which template is used
|
@@ -5422,9 +5480,17 @@ int main(int argc, char ** argv) {
|
5422 | 5480 | SetConsoleCtrlHandler(reinterpret_cast<PHANDLER_ROUTINE>(console_ctrl_handler), true);
|
5423 | 5481 | #endif
|
5424 | 5482 |
|
5425 |
| - LOG_INF("%s: server is listening on %s - starting the main loop\n", __func__, |
5426 |
| - is_sock ? string_format("unix://%s", params.hostname.c_str()).c_str() : |
5427 |
| - string_format("http://%s:%d", params.hostname.c_str(), params.port).c_str()); |
| 5483 | +#ifdef LLAMA_CPP_SYSTEMD_SUPPORT |
| 5484 | + if (using_sd_socket) { |
| 5485 | + LOG_INF("%s: server is listening on systemd socket - starting the main loop\n", __func__); |
| 5486 | + } else { |
| 5487 | +#endif // LLAMA_CPP_SYSTEMD_SUPPORT |
| 5488 | + LOG_INF("%s: server is listening on %s - starting the main loop\n", __func__, |
| 5489 | + is_sock ? string_format("unix://%s", params.hostname.c_str()).c_str() : |
| 5490 | + string_format("http://%s:%d", params.hostname.c_str(), params.port).c_str()); |
| 5491 | +#ifdef LLAMA_CPP_SYSTEMD_SUPPORT |
| 5492 | + } |
| 5493 | +#endif // LLAMA_CPP_SYSTEMD_SUPPORT |
5428 | 5494 |
|
5429 | 5495 | // this call blocks the main thread until queue_tasks.terminate() is called
|
5430 | 5496 | ctx_server.queue_tasks.start_loop();
|
|
0 commit comments