Skip to content
Snippets Groups Projects
Commit a9bbafe9 authored by Marek Vavrusa's avatar Marek Vavrusa
Browse files

Fixed memleak, unified cleanup in case of startup errors.

Change-Id: Ib37d0574e00d2610d5cb2da7ebd59deedf1e8957
parent 86cebf5a
No related branches found
No related tags found
No related merge requests found
......@@ -119,7 +119,6 @@ int pid_write(const char* fn)
int pid_remove(const char* fn)
{
if (unlink(fn) < 0) {
perror("unlink");
return KNOT_EINVAL;
}
......
......@@ -44,6 +44,9 @@ static volatile short sig_req_reload = 0;
static volatile short sig_req_refresh = 0;
static volatile short sig_stopping = 0;
// Cleanup handler
static void do_cleanup(server_t *server, char *configf, char *pidf);
// SIGINT signal handler
void interrupt_handle(int s)
{
......@@ -230,16 +233,13 @@ int main(int argc, char **argv)
log_server_info("Reading configuration '%s' ...\n", config_fn);
int conf_ret = conf_open(config_fn);
if (conf_ret != KNOT_EOK) {
if (conf_ret == KNOT_ENOENT) {
if (conf_ret == KNOT_ENOENT)
log_server_error("Couldn't open configuration file "
"'%s'.\n", config_fn);
} else {
else
log_server_error("Failed to load configuration '%s'.\n",
config_fn);
}
server_wait(server);
server_destroy(&server);
free(config_fn);
do_cleanup(server, config_fn, NULL);
return 1;
} else {
log_server_info("Configured %d interfaces and %d zones.\n",
......@@ -262,9 +262,7 @@ int main(int argc, char **argv)
do_start = 1;
}
if (!do_start) {
free(pidfile);
server_wait(server);
server_destroy(&server);
do_cleanup(server, config_fn, pidfile);
return 1;
}
......@@ -273,7 +271,7 @@ int main(int argc, char **argv)
if (f == NULL) {
log_server_warning("PID file '%s' is not writeable.\n",
pidfile);
free(pidfile);
do_cleanup(server, config_fn, pidfile);
return 1;
}
fclose(f);
......@@ -282,7 +280,7 @@ int main(int argc, char **argv)
if (chown(pidfile, conf()->uid, conf()->gid) < 0) {
log_server_warning("Cannot change PID file ownership\n");
pid_remove(pidfile);
free(pidfile);
do_cleanup(server, config_fn, pidfile);
return 1;
}
......@@ -290,6 +288,7 @@ int main(int argc, char **argv)
log_update_privileges(conf()->uid, conf()->gid);
if (proc_update_privileges(conf()->uid, conf()->gid) != KNOT_EOK) {
pid_remove(pidfile);
do_cleanup(server, config_fn, pidfile);
return 1;
}
......@@ -416,9 +415,6 @@ int main(int argc, char **argv)
res = 1;
}
// Stop server and close log
server_destroy(&server);
// Remove PID file
if (has_pid && pid_remove(pidfile) < 0) {
log_server_warning("Failed to remove PID file.\n");
......@@ -426,16 +422,8 @@ int main(int argc, char **argv)
log_server_info("Shut down.\n");
log_close();
free(pidfile);
// Destroy event loop
evqueue_t *q = evqueue();
evqueue_free(&q);
rcu_unregister_thread();
// Free default config filename if exists
free(config_fn);
do_cleanup(server, config_fn, pidfile);
if (!daemonize) {
fflush(stdout);
......@@ -444,3 +432,21 @@ int main(int argc, char **argv)
return res;
}
static void do_cleanup(server_t *server, char *configf, char *pidf)
{
/* Free alloc'd variables. */
if (server) {
server_wait(server);
server_destroy(&server);
}
free(configf);
free(pidf);
/* Unhook from RCU */
rcu_unregister_thread();
/* Free event loop. */
evqueue_t *q = evqueue();
evqueue_free(&q);
}
......@@ -368,6 +368,17 @@ void tcp_worker_free(tcp_worker_t* w)
free(w);
}
/* Free workers and associated data. */
static void tcp_loop_free(void *data)
{
tcp_worker_t **worker = (tcp_worker_t **)data;
iohandler_t *ioh = worker[0]->ioh;
for (unsigned i = 0; i < ioh->unit->size - 1; ++i)
tcp_worker_free(worker[i]);
free(worker);
}
/*
* Public APIs.
*/
......@@ -523,7 +534,6 @@ int tcp_loop_master(dthread_t *thread)
}
dbg_net("tcp: master thread finished\n");
free(workers);
fdset_destroy(fds);
ref_release(ref);
......@@ -639,7 +649,6 @@ int tcp_loop_worker(dthread_t *thread)
/* Stop whole unit. */
free(qbuf);
dbg_net_verb("tcp: worker %p finished\n", w);
tcp_worker_free(w);
return KNOT_EOK;
}
......@@ -690,5 +699,8 @@ int tcp_loop_unit(iohandler_t *ioh, dt_unit_t *unit)
/* Repurpose first thread as master (unit controller). */
dt_repurpose(unit->threads[0], tcp_loop_master, ioh->state + 0);
/* Create data destructor. */
ioh->dtor = tcp_loop_free;
return KNOT_EOK;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment