Follow-up to eec32e2: Support for removing TTYs at runtime

In commit eec32e2 support for reloading TTY configurations was added.
This patch is a follow-up to that with support for cleaning up and
removing allocated TTYs.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2017-07-09 15:05:32 +02:00
parent 44f69bd575
commit 8aef1e76c3
4 changed files with 99 additions and 6 deletions
+2 -1
View File
@@ -358,7 +358,7 @@ static void parse_dynamic(char *line, struct timeval *mtime)
}
if (MATCH_CMD(line, "tty ", x)) {
tty_register(strip_line(x));
tty_register(strip_line(x), mtime);
return;
}
}
@@ -462,6 +462,7 @@ void conf_reload_dynamic(void)
/* Mark and sweep */
svc_mark_dynamic();
tty_mark();
num = scandir(dir, &e, NULL, alphasort);
if (num < 0) {
+1
View File
@@ -196,6 +196,7 @@ restart:
sm->in_teardown = 1;
cond_reload();
service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD);
tty_reload();
sm->state = SM_RELOAD_WAIT_STATE;
break;
+83 -4
View File
@@ -43,9 +43,48 @@ static pid_t fallback = 0;
#endif
static LIST_HEAD(, tty_node) tty_list = LIST_HEAD_INITIALIZER();
void tty_mark(void)
{
tty_node_t *tty;
LIST_FOREACH(tty, &tty_list, link) {
if (tty->mtime.tv_sec)
tty->dirty = -1;
}
}
void tty_check(tty_node_t *tty, struct timeval *mtime)
{
if (mtime && timercmp(&tty->mtime, mtime, !=))
tty->dirty = 1; /* Modified, restart */
else
tty->dirty = 0; /* Not modified */
/* Update mtime, if given */
tty->mtime.tv_sec = mtime ? mtime->tv_sec : 0;
tty->mtime.tv_usec = mtime ? mtime->tv_usec : 0;
}
void tty_sweep(void)
{
tty_node_t *tty, *tmp;
LIST_FOREACH_SAFE(tty, &tty_list, link, tmp) {
if (tty->mtime.tv_sec && tty->dirty) {
_d("TTY %s dirty, stopping ...", tty->data.name);
tty_stop(&tty->data);
if (tty->dirty == -1) {
_d("TTY %s removed, cleaning up.", tty->data.name);
LIST_REMOVE(tty, link);
tty_unregister(tty);
}
}
}
}
/* tty [!1-9,S] <DEV> [BAUD[,BAUD,...]] [TERM] [noclear] */
int tty_register(char *line)
int tty_register(char *line, struct timeval *mtime)
{
tty_node_t *entry;
int insert = 0, noclear = 0;
@@ -53,7 +92,7 @@ int tty_register(char *line)
char *runlevels = NULL, *term = NULL;
if (!line) {
_e("Invalid input argument");
_e("Missing argument");
return errno = EINVAL;
}
@@ -97,6 +136,27 @@ int tty_register(char *line)
if (insert)
LIST_INSERT_HEAD(&tty_list, entry, link);
tty_check(entry, mtime);
_d("TTY %s is %sdirty", dev, entry->dirty ? "" : "NOT ");
return 0;
}
int tty_unregister(tty_node_t *tty)
{
if (!tty) {
_e("Missing argument");
return errno = EINVAL;
}
if (tty->data.name)
free(tty->data.name);
if (tty->data.baud)
free(tty->data.baud);
if (tty->data.term)
free(tty->data.term);
free(tty);
return 0;
}
@@ -169,7 +229,7 @@ static char *canonicalize(char *tty)
return path;
}
int tty_check(char *dev)
static int tty_exist(char *dev)
{
int fd;
struct termios c;
@@ -210,7 +270,7 @@ void tty_start(finit_tty_t *tty)
if (console && !strcmp(dev, console))
is_console = 1;
if (tty_check(dev)) {
if (tty_exist(dev)) {
_d("%s: Not a valid TTY: %s", dev, strerror(errno));
return;
}
@@ -309,6 +369,25 @@ int tty_respawn(pid_t pid)
return 1;
}
/*
* Called after reload of /etc/finit.d/, stop/start TTYs
*/
void tty_reload(void)
{
tty_node_t *tty;
tty_sweep();
LIST_FOREACH(tty, &tty_list, link) {
if (!tty_enabled(&tty->data))
tty_stop(&tty->data);
else
tty_start(&tty->data);
tty->dirty = 0;
}
}
/* Start all TTYs that exist in the system and are allowed at this runlevel */
void tty_runlevel(void)
{
+13 -1
View File
@@ -43,11 +43,22 @@ typedef struct {
typedef struct tty_node {
LIST_ENTRY(tty_node) link;
finit_tty_t data;
/* XXX: Yes, TTYs should be refactored into a separate SVC type. */
struct timeval mtime; /* Modification time for .conf from /etc/finit.d/ */
int dirty; /* Set if old mtime != new mtime => reloaded,
* or -1 when marked for removal */
} tty_node_t;
//extern LIST_HEAD(, tty_node) tty_list;
int tty_register (char *line);
void tty_mark (void);
void tty_check (tty_node_t *tty, struct timeval *mtime);
void tty_sweep (void);
int tty_register (char *line, struct timeval *mtime);
int tty_unregister (tty_node_t *tty);
tty_node_t *tty_find (char *dev);
size_t tty_num (void);
size_t tty_num_active (void);
@@ -56,6 +67,7 @@ void tty_start (finit_tty_t *tty);
void tty_stop (finit_tty_t *tty);
int tty_enabled (finit_tty_t *tty);
int tty_respawn (pid_t pid);
void tty_reload (void);
void tty_runlevel (void);
#endif /* FINIT_TTY_H_ */