From f973f28492c22fd9aa6952b0a5ab080059b48ed0 Mon Sep 17 00:00:00 2001 From: Zheng shuxin Date: Tue, 27 Jun 2017 17:11:04 +0800 Subject: [PATCH] modify master service --- app/master/daemon/doc/test.txt | 22 +- app/master/daemon/json/struct.gson.cpp | 393 ++++++++++++++++-- app/master/daemon/json/struct.gson.h | 40 ++ app/master/daemon/json/struct.h | 41 +- app/master/daemon/json/struct.stub | 41 +- app/master/daemon/main.cpp | 1 + .../daemon/manage/action/service_start.cpp | 10 +- .../daemon/manage/action/service_stat.cpp | 10 +- .../daemon/manage/action/service_stat.h | 2 +- .../daemon/manage/action/service_stop.cpp | 10 +- .../daemon/manage/action/service_stop.h | 2 +- app/master/daemon/manage/http_client.cpp | 28 ++ app/master/daemon/manage/http_client.h | 1 + app/master/daemon/master/master.h | 8 +- app/master/daemon/master/master_api.cpp | 90 ++-- app/master/daemon/master/master_api.h | 5 +- app/master/daemon/master/master_spawn.cpp | 268 ++++++------ 17 files changed, 740 insertions(+), 232 deletions(-) diff --git a/app/master/daemon/doc/test.txt b/app/master/daemon/doc/test.txt index 34d1776b5..4a7f763e2 100644 --- a/app/master/daemon/doc/test.txt +++ b/app/master/daemon/doc/test.txt @@ -1,8 +1,3 @@ -POST /?cmd=list HTTP/1.0 -Content-Length: 25 - -{ cmd: 'list', data: {}} - POST /?cmd=list HTTP/1.0 Content-Length: 25 Connection: keep-alive @@ -10,20 +5,25 @@ Connection: keep-alive { cmd: 'list', data: {}} POST /?cmd=stat HTTP/1.0 -Content-Length: 49 +Content-Length: 72 Connection: keep-alive -{ cmd: 'stat', data: [{'name':'8084','type':4}]} +{ cmd: 'stat', data: [{'path':'/opt/soft/master/conf/service/web.cf'}]} POST /?cmd=stop HTTP/1.0 -Content-Length: 49 +Content-Length: 72 Connection: keep-alive -{ cmd: 'stop', data: [{'name':'8084','type':4}]} +{ cmd: 'stop', data: [{'path':'/opt/soft/master/conf/service/web.cf'}]} POST /?cmd=start HTTP/1.0 -Content-Length: 64 +Content-Length: 73 Connection: keep-alive -{ cmd: 'start', data: ['/opt/soft/master/conf/service/web.cf']} +{ cmd: 'start', data: [{'path':'/opt/soft/master/conf/service/web.cf'}]} +POST /?cmd=reload HTTP/1.0 +Content-Length: 74 +Connection: keep-alive + +{ cmd: 'reload', data: [{'path':'/opt/soft/master/conf/service/web.cf'}]} diff --git a/app/master/daemon/json/struct.gson.cpp b/app/master/daemon/json/struct.gson.cpp index 80d0f25e5..fd423d40c 100644 --- a/app/master/daemon/json/struct.gson.cpp +++ b/app/master/daemon/json/struct.gson.cpp @@ -136,6 +136,288 @@ namespace acl } + acl::json_node& gson(acl::json &$json, const reload_req_data_t &$obj) + { + acl::json_node &$node = $json.create_node(); + + if (check_nullptr($obj.path)) + $node.add_null("path"); + else + $node.add_text("path", acl::get_value($obj.path)); + + + return $node; + } + + acl::json_node& gson(acl::json &$json, const reload_req_data_t *$obj) + { + return gson ($json, *$obj); + } + + + acl::string gson(const reload_req_data_t &$obj) + { + acl::json $json; + acl::json_node &$node = acl::gson ($json, $obj); + return $node.to_string (); + } + + + std::pair gson(acl::json_node &$node, reload_req_data_t &$obj) + { + acl::json_node *path = $node["path"]; + std::pair $result; + + if(!path ||!($result = gson(*path, &$obj.path), $result.first)) + return std::make_pair(false, "required [reload_req_data_t.path] failed:{"+$result.second+"}"); + + return std::make_pair(true,""); + } + + + std::pair gson(acl::json_node &$node, reload_req_data_t *$obj) + { + return gson($node, *$obj); + } + + + std::pair gson(const acl::string &$str, reload_req_data_t &$obj) + { + acl::json _json; + _json.update($str.c_str()); + if (!_json.finish()) + { + return std::make_pair(false, "json not finish error"); + } + return gson(_json.get_root(), $obj); + } + + + acl::json_node& gson(acl::json &$json, const reload_req_t &$obj) + { + acl::json_node &$node = $json.create_node(); + + if (check_nullptr($obj.cmd)) + $node.add_null("cmd"); + else + $node.add_text("cmd", acl::get_value($obj.cmd)); + + if (check_nullptr($obj.data)) + $node.add_null("data"); + else + $node.add_child("data", acl::gson($json, $obj.data)); + + + return $node; + } + + acl::json_node& gson(acl::json &$json, const reload_req_t *$obj) + { + return gson ($json, *$obj); + } + + + acl::string gson(const reload_req_t &$obj) + { + acl::json $json; + acl::json_node &$node = acl::gson ($json, $obj); + return $node.to_string (); + } + + + std::pair gson(acl::json_node &$node, reload_req_t &$obj) + { + acl::json_node *cmd = $node["cmd"]; + acl::json_node *data = $node["data"]; + std::pair $result; + + if(!cmd ||!($result = gson(*cmd, &$obj.cmd), $result.first)) + return std::make_pair(false, "required [reload_req_t.cmd] failed:{"+$result.second+"}"); + + if(!data ||!data->get_obj()||!($result = gson(*data->get_obj(), &$obj.data), $result.first)) + return std::make_pair(false, "required [reload_req_t.data] failed:{"+$result.second+"}"); + + return std::make_pair(true,""); + } + + + std::pair gson(acl::json_node &$node, reload_req_t *$obj) + { + return gson($node, *$obj); + } + + + std::pair gson(const acl::string &$str, reload_req_t &$obj) + { + acl::json _json; + _json.update($str.c_str()); + if (!_json.finish()) + { + return std::make_pair(false, "json not finish error"); + } + return gson(_json.get_root(), $obj); + } + + + acl::json_node& gson(acl::json &$json, const reload_res_data_t &$obj) + { + acl::json_node &$node = $json.create_node(); + + if (check_nullptr($obj.status)) + $node.add_null("status"); + else + $node.add_number("status", acl::get_value($obj.status)); + + if (check_nullptr($obj.proc_count)) + $node.add_null("proc_count"); + else + $node.add_number("proc_count", acl::get_value($obj.proc_count)); + + if (check_nullptr($obj.proc_signaled)) + $node.add_null("proc_signaled"); + else + $node.add_number("proc_signaled", acl::get_value($obj.proc_signaled)); + + if (check_nullptr($obj.path)) + $node.add_null("path"); + else + $node.add_text("path", acl::get_value($obj.path)); + + + return $node; + } + + acl::json_node& gson(acl::json &$json, const reload_res_data_t *$obj) + { + return gson ($json, *$obj); + } + + + acl::string gson(const reload_res_data_t &$obj) + { + acl::json $json; + acl::json_node &$node = acl::gson ($json, $obj); + return $node.to_string (); + } + + + std::pair gson(acl::json_node &$node, reload_res_data_t &$obj) + { + acl::json_node *status = $node["status"]; + acl::json_node *proc_count = $node["proc_count"]; + acl::json_node *proc_signaled = $node["proc_signaled"]; + acl::json_node *path = $node["path"]; + std::pair $result; + + if(!status ||!($result = gson(*status, &$obj.status), $result.first)) + return std::make_pair(false, "required [reload_res_data_t.status] failed:{"+$result.second+"}"); + + if(!proc_count ||!($result = gson(*proc_count, &$obj.proc_count), $result.first)) + return std::make_pair(false, "required [reload_res_data_t.proc_count] failed:{"+$result.second+"}"); + + if(!proc_signaled ||!($result = gson(*proc_signaled, &$obj.proc_signaled), $result.first)) + return std::make_pair(false, "required [reload_res_data_t.proc_signaled] failed:{"+$result.second+"}"); + + if(!path ||!($result = gson(*path, &$obj.path), $result.first)) + return std::make_pair(false, "required [reload_res_data_t.path] failed:{"+$result.second+"}"); + + return std::make_pair(true,""); + } + + + std::pair gson(acl::json_node &$node, reload_res_data_t *$obj) + { + return gson($node, *$obj); + } + + + std::pair gson(const acl::string &$str, reload_res_data_t &$obj) + { + acl::json _json; + _json.update($str.c_str()); + if (!_json.finish()) + { + return std::make_pair(false, "json not finish error"); + } + return gson(_json.get_root(), $obj); + } + + + acl::json_node& gson(acl::json &$json, const reload_res_t &$obj) + { + acl::json_node &$node = $json.create_node(); + + if (check_nullptr($obj.status)) + $node.add_null("status"); + else + $node.add_number("status", acl::get_value($obj.status)); + + if (check_nullptr($obj.msg)) + $node.add_null("msg"); + else + $node.add_text("msg", acl::get_value($obj.msg)); + + if (check_nullptr($obj.data)) + $node.add_null("data"); + else + $node.add_child("data", acl::gson($json, $obj.data)); + + + return $node; + } + + acl::json_node& gson(acl::json &$json, const reload_res_t *$obj) + { + return gson ($json, *$obj); + } + + + acl::string gson(const reload_res_t &$obj) + { + acl::json $json; + acl::json_node &$node = acl::gson ($json, $obj); + return $node.to_string (); + } + + + std::pair gson(acl::json_node &$node, reload_res_t &$obj) + { + acl::json_node *status = $node["status"]; + acl::json_node *msg = $node["msg"]; + acl::json_node *data = $node["data"]; + std::pair $result; + + if(!status ||!($result = gson(*status, &$obj.status), $result.first)) + return std::make_pair(false, "required [reload_res_t.status] failed:{"+$result.second+"}"); + + if(!msg ||!($result = gson(*msg, &$obj.msg), $result.first)) + return std::make_pair(false, "required [reload_res_t.msg] failed:{"+$result.second+"}"); + + if(!data ||!data->get_obj()||!($result = gson(*data->get_obj(), &$obj.data), $result.first)) + return std::make_pair(false, "required [reload_res_t.data] failed:{"+$result.second+"}"); + + return std::make_pair(true,""); + } + + + std::pair gson(acl::json_node &$node, reload_res_t *$obj) + { + return gson($node, *$obj); + } + + + std::pair gson(const acl::string &$str, reload_res_t &$obj) + { + acl::json _json; + _json.update($str.c_str()); + if (!_json.finish()) + { + return std::make_pair(false, "json not finish error"); + } + return gson(_json.get_root(), $obj); + } + + acl::json_node& gson(acl::json &$json, const req_t &$obj) { acl::json_node &$node = $json.create_node(); @@ -433,6 +715,63 @@ namespace acl } + acl::json_node& gson(acl::json &$json, const start_req_data_t &$obj) + { + acl::json_node &$node = $json.create_node(); + + if (check_nullptr($obj.path)) + $node.add_null("path"); + else + $node.add_text("path", acl::get_value($obj.path)); + + + return $node; + } + + acl::json_node& gson(acl::json &$json, const start_req_data_t *$obj) + { + return gson ($json, *$obj); + } + + + acl::string gson(const start_req_data_t &$obj) + { + acl::json $json; + acl::json_node &$node = acl::gson ($json, $obj); + return $node.to_string (); + } + + + std::pair gson(acl::json_node &$node, start_req_data_t &$obj) + { + acl::json_node *path = $node["path"]; + std::pair $result; + + if(!path ||!($result = gson(*path, &$obj.path), $result.first)) + return std::make_pair(false, "required [start_req_data_t.path] failed:{"+$result.second+"}"); + + return std::make_pair(true,""); + } + + + std::pair gson(acl::json_node &$node, start_req_data_t *$obj) + { + return gson($node, *$obj); + } + + + std::pair gson(const acl::string &$str, start_req_data_t &$obj) + { + acl::json _json; + _json.update($str.c_str()); + if (!_json.finish()) + { + return std::make_pair(false, "json not finish error"); + } + return gson(_json.get_root(), $obj); + } + + acl::json_node& gson(acl::json &$json, const start_req_t &$obj) { acl::json_node &$node = $json.create_node(); @@ -653,15 +992,10 @@ namespace acl { acl::json_node &$node = $json.create_node(); - if (check_nullptr($obj.name)) - $node.add_null("name"); + if (check_nullptr($obj.path)) + $node.add_null("path"); else - $node.add_text("name", acl::get_value($obj.name)); - - if (check_nullptr($obj.type)) - $node.add_null("type"); - else - $node.add_number("type", acl::get_value($obj.type)); + $node.add_text("path", acl::get_value($obj.path)); return $node; @@ -683,15 +1017,11 @@ namespace acl std::pair gson(acl::json_node &$node, stat_req_data_t &$obj) { - acl::json_node *name = $node["name"]; - acl::json_node *type = $node["type"]; + acl::json_node *path = $node["path"]; std::pair $result; - if(!name ||!($result = gson(*name, &$obj.name), $result.first)) - return std::make_pair(false, "required [stat_req_data_t.name] failed:{"+$result.second+"}"); - - if(!type ||!($result = gson(*type, &$obj.type), $result.first)) - return std::make_pair(false, "required [stat_req_data_t.type] failed:{"+$result.second+"}"); + if(!path ||!($result = gson(*path, &$obj.path), $result.first)) + return std::make_pair(false, "required [stat_req_data_t.path] failed:{"+$result.second+"}"); return std::make_pair(true,""); } @@ -860,15 +1190,10 @@ namespace acl { acl::json_node &$node = $json.create_node(); - if (check_nullptr($obj.name)) - $node.add_null("name"); + if (check_nullptr($obj.path)) + $node.add_null("path"); else - $node.add_text("name", acl::get_value($obj.name)); - - if (check_nullptr($obj.type)) - $node.add_null("type"); - else - $node.add_number("type", acl::get_value($obj.type)); + $node.add_text("path", acl::get_value($obj.path)); return $node; @@ -890,15 +1215,11 @@ namespace acl std::pair gson(acl::json_node &$node, stop_req_data_t &$obj) { - acl::json_node *name = $node["name"]; - acl::json_node *type = $node["type"]; + acl::json_node *path = $node["path"]; std::pair $result; - if(!name ||!($result = gson(*name, &$obj.name), $result.first)) - return std::make_pair(false, "required [stop_req_data_t.name] failed:{"+$result.second+"}"); - - if(!type ||!($result = gson(*type, &$obj.type), $result.first)) - return std::make_pair(false, "required [stop_req_data_t.type] failed:{"+$result.second+"}"); + if(!path ||!($result = gson(*path, &$obj.path), $result.first)) + return std::make_pair(false, "required [stop_req_data_t.path] failed:{"+$result.second+"}"); return std::make_pair(true,""); } @@ -997,10 +1318,10 @@ namespace acl else $node.add_number("status", acl::get_value($obj.status)); - if (check_nullptr($obj.name)) - $node.add_null("name"); + if (check_nullptr($obj.path)) + $node.add_null("path"); else - $node.add_text("name", acl::get_value($obj.name)); + $node.add_text("path", acl::get_value($obj.path)); return $node; @@ -1023,14 +1344,14 @@ namespace acl std::pair gson(acl::json_node &$node, stop_res_data_t &$obj) { acl::json_node *status = $node["status"]; - acl::json_node *name = $node["name"]; + acl::json_node *path = $node["path"]; std::pair $result; if(!status ||!($result = gson(*status, &$obj.status), $result.first)) return std::make_pair(false, "required [stop_res_data_t.status] failed:{"+$result.second+"}"); - if(!name ||!($result = gson(*name, &$obj.name), $result.first)) - return std::make_pair(false, "required [stop_res_data_t.name] failed:{"+$result.second+"}"); + if(!path ||!($result = gson(*path, &$obj.path), $result.first)) + return std::make_pair(false, "required [stop_res_data_t.path] failed:{"+$result.second+"}"); return std::make_pair(true,""); } diff --git a/app/master/daemon/json/struct.gson.h b/app/master/daemon/json/struct.gson.h index 7de12741c..5357f3e4c 100644 --- a/app/master/daemon/json/struct.gson.h +++ b/app/master/daemon/json/struct.gson.h @@ -16,6 +16,38 @@ namespace acl std::pair gson(acl::json_node &$node, list_res_t *$obj); std::pair gson(const acl::string &str, list_res_t &$obj); + //reload_req_data_t + acl::string gson(const reload_req_data_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_req_data_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_req_data_t *$obj); + std::pair gson(acl::json_node &$node, reload_req_data_t &$obj); + std::pair gson(acl::json_node &$node, reload_req_data_t *$obj); + std::pair gson(const acl::string &str, reload_req_data_t &$obj); + + //reload_req_t + acl::string gson(const reload_req_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_req_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_req_t *$obj); + std::pair gson(acl::json_node &$node, reload_req_t &$obj); + std::pair gson(acl::json_node &$node, reload_req_t *$obj); + std::pair gson(const acl::string &str, reload_req_t &$obj); + + //reload_res_data_t + acl::string gson(const reload_res_data_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_res_data_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_res_data_t *$obj); + std::pair gson(acl::json_node &$node, reload_res_data_t &$obj); + std::pair gson(acl::json_node &$node, reload_res_data_t *$obj); + std::pair gson(const acl::string &str, reload_res_data_t &$obj); + + //reload_res_t + acl::string gson(const reload_res_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_res_t &$obj); + acl::json_node& gson(acl::json &$json, const reload_res_t *$obj); + std::pair gson(acl::json_node &$node, reload_res_t &$obj); + std::pair gson(acl::json_node &$node, reload_res_t *$obj); + std::pair gson(const acl::string &str, reload_res_t &$obj); + //req_t acl::string gson(const req_t &$obj); acl::json_node& gson(acl::json &$json, const req_t &$obj); @@ -40,6 +72,14 @@ namespace acl std::pair gson(acl::json_node &$node, serv_info_t *$obj); std::pair gson(const acl::string &str, serv_info_t &$obj); + //start_req_data_t + acl::string gson(const start_req_data_t &$obj); + acl::json_node& gson(acl::json &$json, const start_req_data_t &$obj); + acl::json_node& gson(acl::json &$json, const start_req_data_t *$obj); + std::pair gson(acl::json_node &$node, start_req_data_t &$obj); + std::pair gson(acl::json_node &$node, start_req_data_t *$obj); + std::pair gson(const acl::string &str, start_req_data_t &$obj); + //start_req_t acl::string gson(const start_req_t &$obj); acl::json_node& gson(acl::json &$json, const start_req_t &$obj); diff --git a/app/master/daemon/json/struct.h b/app/master/daemon/json/struct.h index 51aab8d97..72192c5b9 100644 --- a/app/master/daemon/json/struct.h +++ b/app/master/daemon/json/struct.h @@ -49,8 +49,7 @@ struct list_res_t : res_t struct stat_req_data_t { - acl::string name; - int type; + acl::string path; }; struct stat_req_t : req_t @@ -65,9 +64,15 @@ struct stat_res_t : res_t ////////////////////////////////////////////////////////////////////////////// +struct start_req_data_t +{ + acl::string path; +}; + struct start_req_t : req_t { - std::vector data; + std::vector data; + }; struct start_res_data_t @@ -87,8 +92,7 @@ struct start_res_t : res_t struct stop_req_data_t { - acl::string name; - int type; + acl::string path; }; struct stop_req_t : req_t @@ -99,10 +103,35 @@ struct stop_req_t : req_t struct stop_res_data_t { int status; - acl::string name; + acl::string path; }; struct stop_res_t : res_t { std::vector data; }; + +////////////////////////////////////////////////////////////////////////////// + +struct reload_req_data_t +{ + acl::string path; +}; + +struct reload_req_t : req_t +{ + std::vector data; +}; + +struct reload_res_data_t +{ + int status; + int proc_count; + int proc_signaled; + acl::string path; +}; + +struct reload_res_t : res_t +{ + std::vector data; +}; diff --git a/app/master/daemon/json/struct.stub b/app/master/daemon/json/struct.stub index 51aab8d97..72192c5b9 100644 --- a/app/master/daemon/json/struct.stub +++ b/app/master/daemon/json/struct.stub @@ -49,8 +49,7 @@ struct list_res_t : res_t struct stat_req_data_t { - acl::string name; - int type; + acl::string path; }; struct stat_req_t : req_t @@ -65,9 +64,15 @@ struct stat_res_t : res_t ////////////////////////////////////////////////////////////////////////////// +struct start_req_data_t +{ + acl::string path; +}; + struct start_req_t : req_t { - std::vector data; + std::vector data; + }; struct start_res_data_t @@ -87,8 +92,7 @@ struct start_res_t : res_t struct stop_req_data_t { - acl::string name; - int type; + acl::string path; }; struct stop_req_t : req_t @@ -99,10 +103,35 @@ struct stop_req_t : req_t struct stop_res_data_t { int status; - acl::string name; + acl::string path; }; struct stop_res_t : res_t { std::vector data; }; + +////////////////////////////////////////////////////////////////////////////// + +struct reload_req_data_t +{ + acl::string path; +}; + +struct reload_req_t : req_t +{ + std::vector data; +}; + +struct reload_res_data_t +{ + int status; + int proc_count; + int proc_signaled; + acl::string path; +}; + +struct reload_res_t : res_t +{ + std::vector data; +}; diff --git a/app/master/daemon/main.cpp b/app/master/daemon/main.cpp index 76e6f2d89..de8e2b779 100644 --- a/app/master/daemon/main.cpp +++ b/app/master/daemon/main.cpp @@ -199,6 +199,7 @@ int main(int argc, char **argv) } #endif + if (0) acl_watchdog_start(watchdog); /* same as trigger servers */ acl_event_loop(acl_var_master_global_event); diff --git a/app/master/daemon/manage/action/service_start.cpp b/app/master/daemon/manage/action/service_start.cpp index d6623f5ef..93f0d42a1 100644 --- a/app/master/daemon/manage/action/service_start.cpp +++ b/app/master/daemon/manage/action/service_start.cpp @@ -20,14 +20,14 @@ bool service_start::run(const start_req_t& req, start_res_t& res) const ACL_MASTER_SERV* serv; size_t n = 0; - for (std::vector::const_iterator cit = req.data.begin(); - cit != req.data.end(); ++cit) + for (std::vector::const_iterator + cit = req.data.begin(); cit != req.data.end(); ++cit) { - const char* name = (*cit).c_str(); - if ((serv = acl_master_start(name)) == NULL) + const char* path = (*cit).path.c_str(); + if ((serv = acl_master_start(path)) == NULL) { data.status = 500; - data.name = name; + data.path = path; } else { diff --git a/app/master/daemon/manage/action/service_stat.cpp b/app/master/daemon/manage/action/service_stat.cpp index 1306c60f5..78ff0d9e5 100644 --- a/app/master/daemon/manage/action/service_stat.cpp +++ b/app/master/daemon/manage/action/service_stat.cpp @@ -14,9 +14,9 @@ #include "master/master_api.h" #include "service_stat.h" -bool service_stat::stat_one(const char* name, int type, serv_info_t& info) +bool service_stat::stat_one(const char* path, serv_info_t& info) { - ACL_MASTER_SERV *serv = acl_master_lookup(name, type); + ACL_MASTER_SERV *serv = acl_master_lookup(path); if (serv == NULL) { @@ -35,9 +35,9 @@ bool service_stat::stat_one(const char* name, int type, serv_info_t& info) info.listen_fd_count = serv->listen_fd_count; if (serv->owner && *serv->owner) - info.owner = serv->owner; + info.owner = serv->owner; if (serv->notify_addr && *serv->notify_addr) - info.notify_addr = serv->notify_addr; + info.notify_addr = serv->notify_addr; if (serv->notify_recipients && *serv->notify_recipients) info.notify_recipients = serv->notify_recipients; @@ -60,7 +60,7 @@ bool service_stat::run(const stat_req_t& req, stat_res_t& res) cit = req.data.begin(); cit != req.data.end(); ++cit) { serv_info_t info; - if (stat_one((*cit).name.c_str(), (*cit).type, info)) + if (stat_one((*cit).path.c_str(), info)) n++; res.data.push_back(info); } diff --git a/app/master/daemon/manage/action/service_stat.h b/app/master/daemon/manage/action/service_stat.h index ace5e9538..b9a9c7e24 100644 --- a/app/master/daemon/manage/action/service_stat.h +++ b/app/master/daemon/manage/action/service_stat.h @@ -25,5 +25,5 @@ public: bool run(const stat_req_t& req, stat_res_t& res); private: - bool stat_one(const char* name, int type, serv_info_t& info); + bool stat_one(const char* path, serv_info_t& info); }; diff --git a/app/master/daemon/manage/action/service_stop.cpp b/app/master/daemon/manage/action/service_stop.cpp index a373dc608..a9eac6148 100644 --- a/app/master/daemon/manage/action/service_stop.cpp +++ b/app/master/daemon/manage/action/service_stop.cpp @@ -14,9 +14,9 @@ #include "master/master_api.h" #include "service_stop.h" -bool service_stop::stop_one(const char* name, int type, stop_res_data_t& data) +bool service_stop::stop_one(const char* path, stop_res_data_t& data) { - if (acl_master_stop(name, type) < 0) + if (acl_master_stop(path) < 0) { data.status = 404; return false; @@ -34,9 +34,9 @@ bool service_stop::run(const stop_req_t& req, stop_res_t& res) cit = req.data.begin(); cit != req.data.end(); ++cit) { stop_res_data_t data; - data.name = (*cit).name; + data.path = (*cit).path; - if (stop_one((*cit).name.c_str(), (*cit).type, data)) + if (stop_one((*cit).path.c_str(), data)) n++; res.data.push_back(data); } @@ -50,7 +50,7 @@ bool service_stop::run(const stop_req_t& req, stop_res_t& res) { res.status = 500; res.msg = "error"; - logger_error("not all service have been started!, n=%d, %d", + logger_error("not all services were started!, n=%d, %d", (int) n, (int) req.data.size()); } diff --git a/app/master/daemon/manage/action/service_stop.h b/app/master/daemon/manage/action/service_stop.h index 6f8f2f8e3..f0760a43e 100644 --- a/app/master/daemon/manage/action/service_stop.h +++ b/app/master/daemon/manage/action/service_stop.h @@ -25,5 +25,5 @@ public: bool run(const stop_req_t& req, stop_res_t& res); private: - bool stop_one(const char* name, int type, stop_res_data_t& data); + bool stop_one(const char* path, stop_res_data_t& data); }; diff --git a/app/master/daemon/manage/http_client.cpp b/app/master/daemon/manage/http_client.cpp index deff7cbb7..bdced1d63 100644 --- a/app/master/daemon/manage/http_client.cpp +++ b/app/master/daemon/manage/http_client.cpp @@ -15,6 +15,7 @@ #include "action/service_stat.h" #include "action/service_start.h" #include "action/service_stop.h" +#include "action/service_reload.h" #include "http_client.h" http_client::http_client(acl::aio_socket_stream *client, int rw_timeout) @@ -75,6 +76,8 @@ int http_client::on_head(int status, void* ctx) { http_client* hc = (http_client*) ctx; + acl_aio_disable_readwrite(hc->conn_); + if (status != HTTP_CHAT_OK) { logger_error("invalid status=%d", status); @@ -121,7 +124,10 @@ int http_client::on_body(int status, char *data, int dlen, void *ctx) hc->json_.update(data); if (status == HTTP_CHAT_OK) + { + acl_aio_disable_readwrite(hc->conn_); return hc->handle() ? 0 : -1; + } return 0; } @@ -169,6 +175,8 @@ bool http_client::handle(void) ret = handle_start(); else if (EQ(cmd, "stop")) ret = handle_stop(); + else if (EQ(cmd, "reload")) + ret = handle_reload(); else { logger_warn("invalid cmd=%s", cmd); acl::string dummy; @@ -280,3 +288,23 @@ bool http_client::handle_start(void) return true; } + +bool http_client::handle_reload(void) +{ + reload_req_t req; + reload_res_t res; + + if (deserialize(json_, req) == false) + { + res.status = 400; + res.msg = "invalid json"; + reply(res.status, res); + return false; + } + + service_reload service; + service.run(req, res); + reply(res.status, res); + + return true; +} diff --git a/app/master/daemon/manage/http_client.h b/app/master/daemon/manage/http_client.h index ec2f54445..56670f8e0 100644 --- a/app/master/daemon/manage/http_client.h +++ b/app/master/daemon/manage/http_client.h @@ -38,6 +38,7 @@ private: bool handle_stat(void); bool handle_stop(void); bool handle_start(void); + bool handle_reload(void); void do_reply(int status, const acl::string& buf); diff --git a/app/master/daemon/master/master.h b/app/master/daemon/master/master.h index 0abf4842d..594485ed4 100644 --- a/app/master/daemon/master/master.h +++ b/app/master/daemon/master/master.h @@ -50,8 +50,8 @@ typedef struct ACL_MASTER_SERV { #if 0 struct ACL_BINHASH *children; /* linkage */ #endif - ACL_RING children; /* linkage children */ - struct ACL_MASTER_SERV *next; /* linkage */ + ACL_RING children; /* linkage of children */ + struct ACL_MASTER_SERV *next; /* linkage of serv */ } ACL_MASTER_SERV; /* @@ -182,6 +182,10 @@ extern void acl_master_spawn(ACL_MASTER_SERV *); extern void acl_master_reap_child(void); extern void acl_master_delete_children(ACL_MASTER_SERV *); extern void acl_master_delete_all_children(void); +extern void acl_master_signal_children(ACL_MASTER_SERV *serv, int signum, + int *nchildren, int *nsignaled); +extern void acl_master_sighup_children(ACL_MASTER_SERV *serv, + int *nchildren, int *nsignaled); /* * master_warning.c diff --git a/app/master/daemon/master/master_api.cpp b/app/master/daemon/master/master_api.cpp index f1a67a939..db446a4e3 100644 --- a/app/master/daemon/master/master_api.cpp +++ b/app/master/daemon/master/master_api.cpp @@ -22,24 +22,34 @@ #include "master.h" #include "master_api.h" -#define STR_SAME !strcmp +#define SAME !strcmp -ACL_MASTER_SERV *acl_master_lookup(const char *name, int type) +ACL_MASTER_SERV *acl_master_lookup(const char *path) { - return acl_master_ent_find(name, type); -} - -ACL_MASTER_SERV *acl_master_start(const char *filepath) -{ - ACL_MASTER_SERV *entry = acl_master_ent_load(filepath), *serv; + ACL_MASTER_SERV *entry = acl_master_ent_load(path), *serv; if (entry == NULL) { acl_msg_error("%s(%d), %s: load %s error %s", __FILE__, - __LINE__, __FUNCTION__, filepath, acl_last_serror()); + __LINE__, __FUNCTION__, path, acl_last_serror()); return NULL; } - serv = acl_master_lookup(entry->name, entry->type); + serv = acl_master_ent_find(entry->name, entry->type); + acl_master_ent_free(entry); + return serv; +} + +ACL_MASTER_SERV *acl_master_start(const char *path) +{ + ACL_MASTER_SERV *entry = acl_master_ent_load(path), *serv; + + if (entry == NULL) { + acl_msg_error("%s(%d), %s: load %s error %s", __FILE__, + __LINE__, __FUNCTION__, path, acl_last_serror()); + return NULL; + } + + serv = acl_master_ent_find(entry->name, entry->type); if (serv != NULL) { acl_msg_error("%s(%d), %s: same service %s %d running", __FILE__, __LINE__, __FUNCTION__, @@ -54,38 +64,52 @@ ACL_MASTER_SERV *acl_master_start(const char *filepath) return entry; } -ACL_MASTER_SERV *acl_master_restart(const char *filepath) +ACL_MASTER_SERV *acl_master_restart(const char *path) { - ACL_MASTER_SERV *entry = acl_master_ent_load(filepath); + (void) acl_master_stop(path); - if (entry == NULL) { - acl_msg_error("%s(%d), %s: load %s error %s", __FILE__, - __LINE__, __FUNCTION__, filepath, acl_last_serror()); - return NULL; - } - - (void) acl_master_stop(entry->name, entry->type); - acl_master_ent_free(entry); - - return acl_master_start(filepath); + return acl_master_start(path); } /* stop one service according the master_service name in configure */ -int acl_master_stop(const char *name, int type) +int acl_master_stop(const char *path) { - ACL_MASTER_SERV *serv, **servp; + ACL_MASTER_SERV *serv = acl_master_lookup(path); + ACL_MASTER_SERV *iter, **servp; - for (servp = &acl_var_master_head; (serv = *servp) != 0;) { - if (serv->type == type && STR_SAME(serv->name, name)) { - *servp = serv->next; - acl_master_service_stop(serv); - acl_master_ent_free(serv); - return 0; - } + if (serv == NULL) { + acl_msg_error("%s(%d), %s: no service, path %s", + __FILE__, __LINE__, __FUNCTION__, path); + return -1; } - acl_msg_warn("%s(%d), %s: service - %s %d not found", - __FILE__, __LINE__, __FUNCTION__, name, type); + for (servp = &acl_var_master_head; (iter = *servp) != 0;) { + if (iter->type == serv->type && SAME(iter->name, serv->name)) { + *servp = iter->next; + acl_master_service_stop(iter); + acl_master_ent_free(iter); + return 0; + } else + servp = &iter->next; + } + + acl_msg_warn("%s(%d), %s: not found service - %s %d, path %s", + __FILE__, __LINE__, __FUNCTION__, serv->name, serv->type, path); + return -1; } + +int acl_master_reload(const char *path, int *nchilden, int *nsignaled) +{ + ACL_MASTER_SERV *serv = acl_master_lookup(path); + + if (serv == NULL) { + acl_msg_error("%s(%d), %s: no service for path %s", + __FILE__, __LINE__, __FUNCTION__, path); + return -1; + } + + acl_master_sighup_children(serv, nchilden, nsignaled); + return 0; +} diff --git a/app/master/daemon/master/master_api.h b/app/master/daemon/master/master_api.h index 51ea63b42..28cceb3f2 100644 --- a/app/master/daemon/master/master_api.h +++ b/app/master/daemon/master/master_api.h @@ -19,10 +19,11 @@ extern "C" { #include "master.h" -ACL_MASTER_SERV *acl_master_lookup(const char *name, int type); +ACL_MASTER_SERV *acl_master_lookup(const char *path); ACL_MASTER_SERV *acl_master_start(const char *path); ACL_MASTER_SERV *acl_master_restart(const char *path); -int acl_master_stop(const char *name, int type); +int acl_master_stop(const char *path); +int acl_master_reload(const char *path, int *nchildren, int *nsignaled); #ifdef __cplusplus diff --git a/app/master/daemon/master/master_spawn.cpp b/app/master/daemon/master/master_spawn.cpp index 306f1ae20..b5c1e5b8b 100644 --- a/app/master/daemon/master/master_spawn.cpp +++ b/app/master/daemon/master/master_spawn.cpp @@ -18,7 +18,7 @@ ACL_BINHASH *acl_var_master_child_table = NULL; static void master_unthrottle(ACL_MASTER_SERV *serv); -void acl_master_spawn_init(void) +void acl_master_spawn_init(void) { if (acl_var_master_child_table == 0) acl_var_master_child_table = acl_binhash_create(0, 0); @@ -43,7 +43,6 @@ static void master_unthrottle_wrapper(int type acl_unused, static void master_unthrottle(ACL_MASTER_SERV *serv) { - /* * Enable process creation within this class. * Disable the "unthrottle" timer just in case @@ -87,15 +86,89 @@ static void master_throttle(ACL_MASTER_SERV *serv) /* acl_master_spawn - spawn off new child process if we can */ +static unsigned master_generation = 0; +static ACL_VSTRING *env_gen = 0; + +static void start_child(ACL_MASTER_SERV *serv) +{ + const char *myname = "start_child"; + ACL_MASTER_NV *nv; + int i, n; + + /* MASTER_FLOW_READ_STREAM has been inited in master_vars.c */ + if (acl_var_master_flow_pipe[0] <= ACL_MASTER_FLOW_READ) + acl_msg_fatal("%s: flow pipe read descriptor <= %d", + myname, ACL_MASTER_FLOW_READ); + if (dup2(acl_var_master_flow_pipe[0], ACL_MASTER_FLOW_READ) < 0) + acl_msg_fatal("%s: dup2: %s", myname, strerror(errno)); + if (close(acl_var_master_flow_pipe[0]) < 0) + acl_msg_fatal("close %d: %s", + acl_var_master_flow_pipe[0], strerror(errno)); + + /* MASTER_FLOW_WRITE_STREAM has been inited in master_vars.c */ + if (acl_var_master_flow_pipe[1] <= ACL_MASTER_FLOW_WRITE) + acl_msg_fatal("%s: flow pipe read descriptor <= %d", + myname, ACL_MASTER_FLOW_WRITE); + if (dup2(acl_var_master_flow_pipe[1], ACL_MASTER_FLOW_WRITE) < 0) + acl_msg_fatal("%s: dup2: %s", myname, strerror(errno)); + if (close(acl_var_master_flow_pipe[1]) < 0) + acl_msg_fatal("close %d: %s", + acl_var_master_flow_pipe[1], strerror(errno)); + + /* status channel */ + acl_vstream_close(serv->status_reader); + + /* MASTER_STAT_STREAM has been inited in master_vars.c*/ + if (serv->status_fd[1] <= ACL_MASTER_STATUS_FD) + acl_msg_fatal("%s: status file descriptor collision", myname); + if (dup2(serv->status_fd[1], ACL_MASTER_STATUS_FD) < 0) + acl_msg_fatal("%s: dup2 status_fd: %s", myname, strerror(errno)); + + close(serv->status_fd[1]); + + for (n = 0; n < serv->listen_fd_count; n++) { + if (serv->listen_fds[n] <= ACL_MASTER_LISTEN_FD + n) + acl_msg_fatal("%s: listen fd collision", myname); + if (dup2(serv->listen_fds[n], ACL_MASTER_LISTEN_FD + n) < 0) + acl_msg_fatal("%s: dup2 listen_fd %d: %s", + myname, serv->listen_fds[n], strerror(errno)); + (void) close(serv->listen_fds[n]); + acl_vstream_free(serv->listen_streams[n]); + } + + acl_vstring_sprintf(env_gen, "%s=%o", ACL_MASTER_GEN_NAME, + master_generation); + if (putenv(acl_vstring_str(env_gen)) < 0) + acl_msg_fatal("%s: putenv: %s", myname, strerror(errno)); + + n = acl_array_size(serv->children_env); + for (i = 0; i < n; i++) { + nv = (ACL_MASTER_NV *) + acl_array_index(serv->children_env, i); + if (nv == NULL) + break; + setenv(nv->name, nv->value, 1); + } + + /* begin to call the child process */ + if (acl_msg_verbose) + acl_msg_info("%s: cmd = %s", myname, serv->path); + + /* help programs written by golang to change runing privilege */ + if (serv->owner && *serv->owner) { + acl_msg_info("%s: acl_chroot_uid %s", myname, serv->owner); + acl_chroot_uid(NULL, serv->owner); + } + + execvp(serv->path, serv->args->argv); + acl_msg_fatal("%s: exec %s: %s", myname, serv->path, strerror(errno)); +} + void acl_master_spawn(ACL_MASTER_SERV *serv) { const char *myname = "acl_master_spawn"; ACL_MASTER_PROC *proc; - ACL_MASTER_NV *nv; - ACL_MASTER_PID pid; - int n, i; - static unsigned master_generation = 0; - static ACL_VSTRING *env_gen = 0; + ACL_MASTER_PID pid; if (env_gen == 0) env_gen = acl_vstring_alloc(100); @@ -135,120 +208,42 @@ void acl_master_spawn(ACL_MASTER_SERV *serv) switch (pid = fork()) { /* - * Error. We're out of some essential resource. - * Best recourse is to try again later. + * Error. We're out of some essential resource. Best recourse is to + * try again later. */ case -1: acl_msg_warn("%s: fork: %s -- throttling", myname, strerror(errno)); master_throttle(serv); - return; + break; - /* - * Child process. Redirect child stdin/stdout to - * the parent-child connection and run the requested - * command. Leave child stderr alone. Disable exit - * handlers: they should be executed by the parent only. - */ + /* + * Child process. Redirect child stdin/stdout to the parent-child + * connection and run the requested command. Leave child stderr alone. + * Disable exit handlers: they should be executed by the parent only. + */ case 0: /* child process */ + start_child(serv); - /* MASTER_FLOW_READ_STREAM has been inited in master_vars.c */ - if (acl_var_master_flow_pipe[0] <= ACL_MASTER_FLOW_READ) - acl_msg_fatal("%s: flow pipe read descriptor <= %d", - myname, ACL_MASTER_FLOW_READ); - if (dup2(acl_var_master_flow_pipe[0], ACL_MASTER_FLOW_READ) < 0) - acl_msg_fatal("%s: dup2: %s", myname, strerror(errno)); - if (close(acl_var_master_flow_pipe[0]) < 0) - acl_msg_fatal("close %d: %s", - acl_var_master_flow_pipe[0], strerror(errno)); - - /* MASTER_FLOW_WRITE_STREAM has been inited in master_vars.c */ - if (acl_var_master_flow_pipe[1] <= ACL_MASTER_FLOW_WRITE) - acl_msg_fatal("%s: flow pipe read descriptor <= %d", - myname, ACL_MASTER_FLOW_WRITE); - if (dup2(acl_var_master_flow_pipe[1], ACL_MASTER_FLOW_WRITE) < 0) - acl_msg_fatal("%s: dup2: %s", myname, strerror(errno)); - if (close(acl_var_master_flow_pipe[1]) < 0) - acl_msg_fatal("close %d: %s", - acl_var_master_flow_pipe[1], strerror(errno)); - - /* status channel */ - acl_vstream_close(serv->status_reader); - - /* MASTER_STAT_STREAM has been inited in master_vars.c*/ - if (serv->status_fd[1] <= ACL_MASTER_STATUS_FD) - acl_msg_fatal("%s: status file descriptor collision", - myname); - if (dup2(serv->status_fd[1], ACL_MASTER_STATUS_FD) < 0) - acl_msg_fatal("%s: dup2 status_fd: %s", - myname, strerror(errno)); - - close(serv->status_fd[1]); - - for (n = 0; n < serv->listen_fd_count; n++) { - if (serv->listen_fds[n] <= ACL_MASTER_LISTEN_FD + n) - acl_msg_fatal("%s(%d)->%s: " - "listen file descriptor collision", - __FILE__, __LINE__, myname); - if (dup2(serv->listen_fds[n], ACL_MASTER_LISTEN_FD + n) < 0) - acl_msg_fatal("%s: dup2 listen_fd %d: %s", - myname, serv->listen_fds[n], strerror(errno)); - (void) close(serv->listen_fds[n]); - if (acl_msg_verbose) - acl_msg_info(">>>fd is: %d<<", ACL_MASTER_LISTEN_FD + n); - acl_vstream_free(serv->listen_streams[n]); - } - - acl_vstring_sprintf(env_gen, "%s=%o", - ACL_MASTER_GEN_NAME, master_generation); - if (putenv(acl_vstring_str(env_gen)) < 0) - acl_msg_fatal("%s: putenv: %s", myname, strerror(errno)); - - n = acl_array_size(serv->children_env); - for (i = 0; i < n; i++) { - nv = (ACL_MASTER_NV *) - acl_array_index(serv->children_env, i); - if (nv == NULL) - break; - setenv(nv->name, nv->value, 1); - } - - /* begin to call the child process */ - if (acl_msg_verbose) - acl_msg_info("%s(%d)->%s: cmd = %s", - __FILE__, __LINE__, myname, serv->path); - - /* help programs written by golang to change runing privilege */ - if (serv->owner && *serv->owner) { - acl_msg_info("%s(%d)->%s: acl_chroot_uid %s", - __FILE__, __LINE__, myname, serv->owner); - acl_chroot_uid(NULL, serv->owner); - } - - execvp(serv->path, serv->args->argv); - acl_msg_fatal("%s(%d)->%s: exec %s: %s", __FILE__, __LINE__, - myname, serv->path, strerror(errno)); - exit(1); /* NOTREACHED */ + exit(1); - /* - * Parent. Fill in a process member data structure - * and set up links between child and process. - * Say this process has become available. - * If this service has a wakeup timer that is turned - * on only when the service is actually used, - * turn on the wakeup timer. - */ + /* + * Parent. Fill in a process member data structure and set up links + * between child and process. Say this process has become available. + * If this service has a wakeup timer that is turned on only when the + * service is actually used, turn on the wakeup timer. + */ default: /* the parent process */ if (acl_msg_verbose) - acl_msg_info("spawn command %s; pid %d", serv->path, pid); + acl_msg_info("spawn cmd %s pid %d", serv->path, pid); proc = (ACL_MASTER_PROC *) acl_mycalloc(1, sizeof(ACL_MASTER_PROC)); proc->serv = serv; proc->pid = pid; proc->gen = master_generation; proc->use_count = 0; proc->avail = 0; - acl_binhash_enter(acl_var_master_child_table, (char *) &pid, - sizeof(pid), (char *) proc); + acl_binhash_enter(acl_var_master_child_table, + (char *) &pid, sizeof(pid), (char *) proc); acl_ring_prepend(&serv->children, &proc->me); serv->total_proc++; acl_master_avail_more(serv, proc); @@ -256,8 +251,7 @@ void acl_master_spawn(ACL_MASTER_SERV *serv) serv->flags &= ~ACL_MASTER_FLAG_CONDWAKE; acl_master_wakeup_init(serv); if (acl_msg_verbose) - acl_msg_info("start conditional timer for %s", - serv->name); + acl_msg_info("start timer for %s", serv->name); } break; @@ -306,11 +300,11 @@ static void master_delete_child(ACL_MASTER_PROC *proc) void acl_master_reap_child(void) { const char *myname = "acl_master_reap_child"; - ACL_MASTER_SERV *serv; - ACL_MASTER_PROC *proc; - ACL_MASTER_PID pid; + ACL_MASTER_SERV *serv; + ACL_MASTER_PROC *proc; + ACL_MASTER_PID pid; ACL_WAIT_STATUS_T status; - char buf[256]; + char buf[256]; /* * Pick up termination status of all dead children. @@ -321,11 +315,11 @@ void acl_master_reap_child(void) */ while ((pid = waitpid((pid_t) - 1, &status, WNOHANG)) > 0) { if (acl_msg_verbose) - acl_msg_info("master_reap_child: pid %d", pid); + acl_msg_info("%s: pid %d", myname, pid); - if ((proc = (ACL_MASTER_PROC *) - acl_binhash_find(acl_var_master_child_table, - (char *) &pid, sizeof(pid))) == 0) { + proc = (ACL_MASTER_PROC *) acl_binhash_find( + acl_var_master_child_table, &pid, sizeof(pid)); + if (proc == NULL) { acl_msg_warn("master_reap: unknown pid: %d", pid); continue; } @@ -338,12 +332,14 @@ void acl_master_reap_child(void) serv = proc->serv; if (WIFEXITED(status)) { + acl_msg_warn("%s(%d), %s: process %s pid %d " "exit status %d", __FILE__, __LINE__, myname, serv->path, pid, WEXITSTATUS(status)); + if (serv->notify_addr != NULL - && serv->notify_recipients != NULL) - { + && serv->notify_recipients != NULL) { + snprintf(buf, sizeof(buf), "exit status %d", WEXITSTATUS(status)); master_warning(serv->notify_addr, @@ -353,12 +349,12 @@ void acl_master_reap_child(void) } if (WIFSIGNALED(status)) { + acl_msg_warn("%s(%d), %s: process %s pid %d killed" " by signal %d", __FILE__, __LINE__, myname, serv->path, pid, WTERMSIG(status)); - if (serv->notify_addr != NULL - && serv->notify_recipients != NULL) - { + + if (serv->notify_addr && serv->notify_recipients) { snprintf(buf, sizeof(buf), "killed by %d", WTERMSIG(status)); master_warning(serv->notify_addr, @@ -419,3 +415,37 @@ void acl_master_delete_all_children(void) acl_master_ent_free(serv); } } + +void acl_master_signal_children(ACL_MASTER_SERV *serv, int signum, + int *nchildren, int *nsignaled) +{ + const char *myname = "acl_master_signal_children"; + ACL_RING_ITER iter; + ACL_MASTER_PROC *proc; + int n = 0; + + acl_ring_foreach(iter, &serv->children) { + proc = acl_ring_to_appl(iter.ptr, ACL_MASTER_PROC, me); + acl_assert(proc); + if (kill(proc->pid, signum) < 0) + acl_msg_warn("%s: kill child %d, path %s error %s", + myname, proc->pid, serv->path, strerror(errno)); + else + n++; + } + + if (nchildren) + *nchildren = acl_ring_size(&serv->children); + if (nsignaled) + *nsignaled = n; + + acl_msg_info("%s: service %s, path %s, signal %d, children %d," + " signaled %d", myname, serv->name, serv->path, + signum, acl_ring_size(&serv->children), n); +} + +void acl_master_sighup_children(ACL_MASTER_SERV *serv, + int *nchildren, int *nsignaled) +{ + acl_master_signal_children(serv, SIGHUP, nchildren, nsignaled); +}