diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-02-18 15:23:30 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-02-18 15:33:34 +0200 |
commit | 0a55965bcc28928ae17ca39e3b8e35adf11ea09c (patch) | |
tree | ed8f6543999caef2d81b517fb90182be4a984fda | |
parent | d5302613a00915076b945b25b50eb6b376121955 (diff) | |
download | pies-0a55965bcc28928ae17ca39e3b8e35adf11ea09c.tar.gz pies-0a55965bcc28928ae17ca39e3b8e35adf11ea09c.tar.bz2 |
Fix activation/deactivation of network listeners.
* src/ctl.c (prog_active): New function.
(prog_serialize): Use prog_active to report prog's activity state.
For listener components, return also their service and tcpmux master
names, if applicable.
(fun_stop): Stop listeners as well.
(fun_start): Start listeners.
(ctlio_end): Don't close fd: this is done by deregister_socket
* src/inetd-bi.c (tcpmux_help): Don't list inactive components.
* src/prog.h (prog_activate_listener)
(prog_deactivate_listener): New protos.
* src/progman.c (prog_lookup_by_tag)
(prog_lookup_by_service): Remove.
(progman_cleanup): Fix coredump (premature free).
(progman_stop_component): If component is a listener, deactivate it.
(prog_activate_listener)
(prog_deactivate_listener): New functions.
* src/socket.c (delete_sockinst): Close the socket descriptor.
* src/sysvinit.c (sysvinit_fifo_handler, create_fifo): Don't close fd,
leave that to deregister_socket.
-rw-r--r-- | src/ctl.c | 67 | ||||
-rw-r--r-- | src/inetd-bi.c | 3 | ||||
-rw-r--r-- | src/prog.h | 3 | ||||
-rw-r--r-- | src/progman.c | 68 | ||||
-rw-r--r-- | src/socket.c | 1 | ||||
-rw-r--r-- | src/sysvinit.c | 6 |
6 files changed, 100 insertions, 48 deletions
@@ -532,7 +532,6 @@ static int | |||
532 | ctlio_end (int fd, struct ctlio *io) | 532 | ctlio_end (int fd, struct ctlio *io) |
533 | { | 533 | { |
534 | deregister_socket (fd); | 534 | deregister_socket (fd); |
535 | close (fd); | ||
536 | ctlio_destroy (io); | 535 | ctlio_destroy (io); |
537 | return 1; | 536 | return 1; |
538 | } | 537 | } |
@@ -1816,6 +1815,24 @@ selector (struct prog *prog, void *data) | |||
1816 | return 0; | 1815 | return 0; |
1817 | } | 1816 | } |
1818 | 1817 | ||
1818 | /* Return true if PROG is active. For TCPMUX progs, this takes into account | ||
1819 | the state of the master listener. | ||
1820 | FIXME: Ideally all TCPMUXen must form a list attached to their master | ||
1821 | listener. When this is fixed, this function will disappear. */ | ||
1822 | static int | ||
1823 | prog_active (struct prog *prog) | ||
1824 | { | ||
1825 | if (prog->v.p.active) | ||
1826 | { | ||
1827 | if (ISCF_TCPMUX (prog->v.p.comp->flags)) | ||
1828 | { | ||
1829 | prog = progman_locate (prog->v.p.comp->tcpmux); | ||
1830 | return prog && prog->v.p.active; | ||
1831 | } | ||
1832 | } | ||
1833 | return prog->v.p.active; | ||
1834 | } | ||
1835 | |||
1819 | static struct json_value * | 1836 | static struct json_value * |
1820 | prog_serialize (struct json_value *ret, struct prog *prog) | 1837 | prog_serialize (struct json_value *ret, struct prog *prog) |
1821 | { | 1838 | { |
@@ -1829,14 +1846,23 @@ prog_serialize (struct json_value *ret, struct prog *prog) | |||
1829 | FORMAT_IDX (ret, "mode", pies_comp_mode_str, prog->v.p.comp->mode); | 1846 | FORMAT_IDX (ret, "mode", pies_comp_mode_str, prog->v.p.comp->mode); |
1830 | FORMAT_IDX (ret, "status", pies_status_str, prog->v.p.status); | 1847 | FORMAT_IDX (ret, "status", pies_status_str, prog->v.p.status); |
1831 | 1848 | ||
1832 | json_object_set_bool (ret, "active", prog->v.p.active); | 1849 | json_object_set_bool (ret, "active", prog_active (prog)); |
1833 | 1850 | ||
1834 | if (prog->pid) | 1851 | if (prog->pid) |
1835 | json_object_set_number (ret, "PID", prog->pid); | 1852 | json_object_set_number (ret, "PID", prog->pid); |
1836 | else if (prog->v.p.status == status_listener | 1853 | else if (prog->v.p.status == status_listener) |
1837 | && prog->v.p.comp->socket_url) | 1854 | { |
1838 | json_object_set_string (ret, "URL", "%s", | 1855 | if (prog->v.p.comp->socket_url) |
1839 | prog->v.p.comp->socket_url->string); | 1856 | json_object_set_string (ret, "URL", "%s", |
1857 | prog->v.p.comp->socket_url->string); | ||
1858 | if (prog->v.p.comp->service) | ||
1859 | json_object_set_string (ret, "service", "%s", | ||
1860 | prog->v.p.comp->service); | ||
1861 | if (ISCF_TCPMUX (prog->v.p.comp->flags) && prog->v.p.comp->tcpmux) | ||
1862 | json_object_set_string (ret, "master", "%s", | ||
1863 | prog->v.p.comp->tcpmux); | ||
1864 | } | ||
1865 | |||
1840 | 1866 | ||
1841 | if (prog->v.p.comp->runlevels) | 1867 | if (prog->v.p.comp->runlevels) |
1842 | json_object_set_string (ret, "runlevels", "%s", | 1868 | json_object_set_string (ret, "runlevels", "%s", |
@@ -1872,19 +1898,16 @@ fun_list (struct json_value *result, struct prog *prog) | |||
1872 | static int | 1898 | static int |
1873 | fun_stop (struct json_value *result, struct prog *prog) | 1899 | fun_stop (struct json_value *result, struct prog *prog) |
1874 | { | 1900 | { |
1875 | if (prog->v.p.active && prog->v.p.status == status_stopped) | 1901 | if (!prog->v.p.active) |
1876 | { | 1902 | { |
1877 | |||
1878 | json_object_set_string (result, "status", "ER"); | 1903 | json_object_set_string (result, "status", "ER"); |
1879 | json_object_set_string (result, "error_message", "already stopped"); | 1904 | json_object_set_string (result, "error_message", "already stopped"); |
1880 | return 1; | 1905 | return 1; |
1881 | } | 1906 | } |
1882 | else | 1907 | |
1883 | { | 1908 | prog->v.p.active = 0; |
1884 | prog->v.p.active = 0; | 1909 | progman_stop_component (&prog); |
1885 | progman_stop_component (&prog); | 1910 | json_object_set_string (result, "status", "OK"); |
1886 | json_object_set_string (result, "status", "OK"); | ||
1887 | } | ||
1888 | return 0; | 1911 | return 0; |
1889 | } | 1912 | } |
1890 | 1913 | ||
@@ -1895,7 +1918,6 @@ fun_start (struct json_value *result, struct prog *prog) | |||
1895 | { | 1918 | { |
1896 | case status_stopped: | 1919 | case status_stopped: |
1897 | prog->v.p.comp->flags &= ~CF_DISABLED; | 1920 | prog->v.p.comp->flags &= ~CF_DISABLED; |
1898 | prog->v.p.active = 1; | ||
1899 | json_object_set_string (result, "status", "OK"); | 1921 | json_object_set_string (result, "status", "OK"); |
1900 | break; | 1922 | break; |
1901 | 1923 | ||
@@ -1906,12 +1928,25 @@ fun_start (struct json_value *result, struct prog *prog) | |||
1906 | prog->v.p.timestamp = 0; | 1928 | prog->v.p.timestamp = 0; |
1907 | json_object_set_string (result, "status", "OK"); | 1929 | json_object_set_string (result, "status", "OK"); |
1908 | break; | 1930 | break; |
1931 | |||
1932 | case status_listener: | ||
1933 | if (prog_activate_listener (prog) == 0) | ||
1934 | json_object_set_string (result, "status", "OK"); | ||
1935 | else | ||
1936 | { | ||
1937 | json_object_set_string (result, "status", "ER"); | ||
1938 | /* FIXME: error message */ | ||
1939 | json_object_set_string (result, "error_message", | ||
1940 | "can't open socket"); | ||
1941 | } | ||
1942 | break; | ||
1909 | 1943 | ||
1910 | default: | 1944 | default: |
1911 | json_object_set_string (result, "status", "ER"); | 1945 | json_object_set_string (result, "status", "ER"); |
1912 | json_object_set_string (result, "error_message", "already running"); | 1946 | json_object_set_string (result, "error_message", "already running"); |
1913 | return 1; | 1947 | return 1; |
1914 | } | 1948 | } |
1949 | prog->v.p.active = 1; | ||
1915 | return 0; | 1950 | return 0; |
1916 | } | 1951 | } |
1917 | 1952 | ||
diff --git a/src/inetd-bi.c b/src/inetd-bi.c index de9cfa0..d0d3ea4 100644 --- a/src/inetd-bi.c +++ b/src/inetd-bi.c | |||
@@ -15,6 +15,7 @@ | |||
15 | along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ | 15 | along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ |
16 | 16 | ||
17 | #include "pies.h" | 17 | #include "pies.h" |
18 | #include "prog.h" | ||
18 | #include <netdb.h> | 19 | #include <netdb.h> |
19 | 20 | ||
20 | #define INTBUFSIZE 8192 | 21 | #define INTBUFSIZE 8192 |
@@ -303,7 +304,7 @@ tcpmux_help (struct component *comp, void *data) | |||
303 | { | 304 | { |
304 | int *pfd = data; | 305 | int *pfd = data; |
305 | 306 | ||
306 | if (!(comp->flags & CF_DISABLED) && ISCF_TCPMUX (comp->flags)) | 307 | if (ISCF_TCPMUX (comp->flags) && comp->prog && comp->prog->v.p.active) |
307 | { | 308 | { |
308 | fd_report (*pfd, comp->service); | 309 | fd_report (*pfd, comp->service); |
309 | fd_report (*pfd, "\r\n"); | 310 | fd_report (*pfd, "\r\n"); |
@@ -91,3 +91,6 @@ void prog_stop (struct prog *prog, int sig); | |||
91 | void progman_stop_component (struct prog **prog); | 91 | void progman_stop_component (struct prog **prog); |
92 | 92 | ||
93 | char const *prog_tag (struct prog const *prog); | 93 | char const *prog_tag (struct prog const *prog); |
94 | |||
95 | int prog_activate_listener (struct prog *prog); | ||
96 | void prog_deactivate_listener (struct prog *prog); | ||
diff --git a/src/progman.c b/src/progman.c index 9641629..2c38b63 100644 --- a/src/progman.c +++ b/src/progman.c | |||
@@ -72,28 +72,6 @@ prog_lookup_by_pid (pid_t pid) | |||
72 | return prog; | 72 | return prog; |
73 | } | 73 | } |
74 | 74 | ||
75 | struct prog * | ||
76 | prog_lookup_by_tag (const char *tag) | ||
77 | { | ||
78 | struct prog *prog; | ||
79 | for (prog = proghead; prog; prog = prog->next) | ||
80 | if (strcmp (prog_tag (prog), tag) == 0) | ||
81 | break; | ||
82 | return prog; | ||
83 | } | ||
84 | |||
85 | struct prog * | ||
86 | prog_lookup_by_service (const char *service) | ||
87 | { | ||
88 | struct prog *prog; | ||
89 | for (prog = proghead; prog; prog = prog->next) | ||
90 | if (IS_COMPONENT (prog) | ||
91 | && prog->v.p.comp->service | ||
92 | && strcmp (prog->v.p.comp->service, service) == 0) | ||
93 | break; | ||
94 | return prog; | ||
95 | } | ||
96 | |||
97 | struct component * | 75 | struct component * |
98 | progman_lookup_component (const char *tag) | 76 | progman_lookup_component (const char *tag) |
99 | { | 77 | { |
@@ -190,8 +168,8 @@ destroy_prog (struct prog **pp) | |||
190 | { | 168 | { |
191 | case TYPE_COMPONENT: | 169 | case TYPE_COMPONENT: |
192 | component_ref_decr (p->v.p.comp); | 170 | component_ref_decr (p->v.p.comp); |
193 | if (p->v.p.status == status_listener) | 171 | if (p->v.p.status == status_listener && p->v.p.socket != -1) |
194 | deregister_socket (p->v.p.socket); | 172 | deregister_socket (p->v.p.socket); |
195 | break; | 173 | break; |
196 | 174 | ||
197 | case TYPE_REDIRECTOR: | 175 | case TYPE_REDIRECTOR: |
@@ -2311,7 +2289,6 @@ progman_cleanup (int expect_term) | |||
2311 | } | 2289 | } |
2312 | 2290 | ||
2313 | prog_stop_redirectors (prog); | 2291 | prog_stop_redirectors (prog); |
2314 | destroy_prog (&prog); | ||
2315 | if (listener->v.p.num_instances == 0 | 2292 | if (listener->v.p.num_instances == 0 |
2316 | && !component_is_active (prog->v.p.comp)) | 2293 | && !component_is_active (prog->v.p.comp)) |
2317 | destroy_prog (&listener); | 2294 | destroy_prog (&listener); |
@@ -2322,6 +2299,7 @@ progman_cleanup (int expect_term) | |||
2322 | if (listener->v.p.comp->flags & CF_WAIT) | 2299 | if (listener->v.p.comp->flags & CF_WAIT) |
2323 | enable_socket (listener->v.p.socket); | 2300 |