conf: port state_clients to new list type

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2021-08-25 14:38:00 +02:00
parent 2345ad43f0
commit d2e75eba7e
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
5 changed files with 25 additions and 42 deletions

View File

@ -1905,22 +1905,14 @@ static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
const lxc_cmd_t cmd) const lxc_cmd_t cmd)
{ {
if (cmd == LXC_CMD_ADD_STATE_CLIENT) { if (cmd == LXC_CMD_ADD_STATE_CLIENT) {
struct lxc_list *cur, *next; struct lxc_state_client *client, *nclient;
lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
struct lxc_state_client *client = cur->elem;
list_for_each_entry_safe(client, nclient, &handler->conf->state_clients, head) {
if (client->clientfd != fd) if (client->clientfd != fd)
continue; continue;
/* list_del(&client->head);
* Only kick client from list so it can't be found free(client);
* anymore. The actual close happens, as for all other
* file descriptors, below.
*/
lxc_list_del(cur);
free(cur->elem);
free(cur);
/* /*
* No need to walk the whole list. If we found the state * No need to walk the whole list. If we found the state

View File

@ -168,7 +168,6 @@ int lxc_add_state_client(int state_client_fd, struct lxc_handler *handler,
lxc_state_t states[MAX_STATE]) lxc_state_t states[MAX_STATE])
{ {
__do_free struct lxc_state_client *newclient = NULL; __do_free struct lxc_state_client *newclient = NULL;
__do_free struct lxc_list *tmplist = NULL;
int state; int state;
newclient = zalloc(sizeof(*newclient)); newclient = zalloc(sizeof(*newclient));
@ -179,14 +178,10 @@ int lxc_add_state_client(int state_client_fd, struct lxc_handler *handler,
memcpy(newclient->states, states, sizeof(newclient->states)); memcpy(newclient->states, states, sizeof(newclient->states));
newclient->clientfd = state_client_fd; newclient->clientfd = state_client_fd;
tmplist = zalloc(sizeof(*tmplist));
if (!tmplist)
return -ENOMEM;
state = handler->state; state = handler->state;
if (states[state] != 1) { if (states[state] != 1) {
lxc_list_add_elem(tmplist, move_ptr(newclient)); list_add_tail(&newclient->head, &handler->conf->state_clients);
lxc_list_add_tail(&handler->conf->state_clients, move_ptr(tmplist)); move_ptr(newclient);
} else { } else {
TRACE("Container already in requested state"); TRACE("Container already in requested state");
return state; return state;

View File

@ -3395,7 +3395,7 @@ struct lxc_conf *lxc_conf_init(void)
for (i = 0; i < NUM_LXC_HOOKS; i++) for (i = 0; i < NUM_LXC_HOOKS; i++)
lxc_list_init(&new->hooks[i]); lxc_list_init(&new->hooks[i]);
lxc_list_init(&new->groups); lxc_list_init(&new->groups);
lxc_list_init(&new->state_clients); INIT_LIST_HEAD(&new->state_clients);
new->lsm_aa_profile = NULL; new->lsm_aa_profile = NULL;
lxc_list_init(&new->lsm_aa_raw); lxc_list_init(&new->lsm_aa_raw);
new->lsm_se_context = NULL; new->lsm_se_context = NULL;

View File

@ -299,6 +299,7 @@ __hidden extern char *lxchook_names[NUM_LXC_HOOKS];
struct lxc_state_client { struct lxc_state_client {
int clientfd; int clientfd;
lxc_state_t states[MAX_STATE]; lxc_state_t states[MAX_STATE];
struct list_head head;
}; };
typedef enum lxc_bpf_devices_rule_t { typedef enum lxc_bpf_devices_rule_t {
@ -486,7 +487,7 @@ struct lxc_conf {
char *init_cwd; char *init_cwd;
/* A list of clients registered to be informed about a container state. */ /* A list of clients registered to be informed about a container state. */
struct lxc_list state_clients; struct list_head state_clients;
/* sysctls */ /* sysctls */
struct lxc_list sysctls; struct lxc_list sysctls;

View File

@ -245,6 +245,7 @@ int lxc_check_inherited(struct lxc_conf *conf, bool closeall,
DIR *dir; DIR *dir;
struct dirent *direntp; struct dirent *direntp;
unsigned int listen_fds_max; unsigned int listen_fds_max;
struct lxc_state_client *client, *nclient;
if (conf && conf->close_all_fds) if (conf && conf->close_all_fds)
closeall = true; closeall = true;
@ -267,7 +268,6 @@ restart:
while ((direntp = readdir(dir))) { while ((direntp = readdir(dir))) {
int ret; int ret;
struct lxc_list *cur;
bool matched = false; bool matched = false;
if (strequal(direntp->d_name, ".")) if (strequal(direntp->d_name, "."))
@ -292,9 +292,7 @@ restart:
/* Keep state clients that wait on reboots. */ /* Keep state clients that wait on reboots. */
if (conf) { if (conf) {
lxc_list_for_each(cur, &conf->state_clients) { list_for_each_entry_safe(client, nclient, &conf->state_clients, head) {
struct lxc_state_client *client = cur->elem;
if (client->clientfd != fd) if (client->clientfd != fd)
continue; continue;
@ -472,10 +470,13 @@ static int signal_handler(int fd, uint32_t events, void *data,
int lxc_serve_state_clients(const char *name, struct lxc_handler *handler, int lxc_serve_state_clients(const char *name, struct lxc_handler *handler,
lxc_state_t state) lxc_state_t state)
{ {
struct lxc_msg msg = {
.type = lxc_msg_state,
.value = state,
};
size_t retlen; size_t retlen;
ssize_t ret; ssize_t ret;
struct lxc_list *cur, *next; struct lxc_state_client *client, *nclient;
struct lxc_msg msg = {.type = lxc_msg_state, .value = state};
if (state == THAWED) if (state == THAWED)
handler->state = RUNNING; handler->state = RUNNING;
@ -484,16 +485,14 @@ int lxc_serve_state_clients(const char *name, struct lxc_handler *handler,
TRACE("Set container state to %s", lxc_state2str(state)); TRACE("Set container state to %s", lxc_state2str(state));
if (lxc_list_empty(&handler->conf->state_clients)) if (list_empty(&handler->conf->state_clients))
return log_trace(0, "No state clients registered"); return log_trace(0, "No state clients registered");
retlen = strlcpy(msg.name, name, sizeof(msg.name)); retlen = strlcpy(msg.name, name, sizeof(msg.name));
if (retlen >= sizeof(msg.name)) if (retlen >= sizeof(msg.name))
return -E2BIG; return -E2BIG;
lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) { list_for_each_entry_safe(client, nclient, &handler->conf->state_clients, head) {
struct lxc_state_client *client = cur->elem;
if (client->states[state] == 0) { if (client->states[state] == 0) {
TRACE("State %s not registered for state client %d", TRACE("State %s not registered for state client %d",
lxc_state2str(state), client->clientfd); lxc_state2str(state), client->clientfd);
@ -508,10 +507,9 @@ int lxc_serve_state_clients(const char *name, struct lxc_handler *handler,
SYSERROR("Failed to send message to client"); SYSERROR("Failed to send message to client");
/* kick client from list */ /* kick client from list */
lxc_list_del(cur); list_del(&client->head);
close(client->clientfd); close(client->clientfd);
free(cur->elem); free(client);
free(cur);
} }
return 0; return 0;
@ -706,7 +704,7 @@ struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
handler->state_socket_pair[0] = -EBADF; handler->state_socket_pair[0] = -EBADF;
handler->state_socket_pair[1] = -EBADF; handler->state_socket_pair[1] = -EBADF;
if (handler->conf->reboot == REBOOT_NONE) if (handler->conf->reboot == REBOOT_NONE)
lxc_list_init(&handler->conf->state_clients); INIT_LIST_HEAD(&handler->conf->state_clients);
for (lxc_namespace_t idx = 0; idx < LXC_NS_MAX; idx++) { for (lxc_namespace_t idx = 0; idx < LXC_NS_MAX; idx++) {
handler->nsfd[idx] = -EBADF; handler->nsfd[idx] = -EBADF;
@ -915,9 +913,9 @@ void lxc_expose_namespace_environment(const struct lxc_handler *handler)
void lxc_end(struct lxc_handler *handler) void lxc_end(struct lxc_handler *handler)
{ {
int ret; int ret;
struct lxc_list *cur, *next;
const char *name = handler->name; const char *name = handler->name;
struct cgroup_ops *cgroup_ops = handler->cgroup_ops; struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
struct lxc_state_client *client, *nclient;
/* The STOPPING state is there for future cleanup code which can take /* The STOPPING state is there for future cleanup code which can take
* awhile. * awhile.
@ -1009,19 +1007,16 @@ void lxc_end(struct lxc_handler *handler)
/* The command socket is now closed, no more state clients can register /* The command socket is now closed, no more state clients can register
* themselves from now on. So free the list of state clients. * themselves from now on. So free the list of state clients.
*/ */
lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) { list_for_each_entry_safe(client, nclient, &handler->conf->state_clients, head) {
struct lxc_state_client *client = cur->elem;
/* Keep state clients that want to be notified about reboots. */ /* Keep state clients that want to be notified about reboots. */
if ((handler->conf->reboot > REBOOT_NONE) && if ((handler->conf->reboot > REBOOT_NONE) &&
(client->states[RUNNING] == 2)) (client->states[RUNNING] == 2))
continue; continue;
/* close state client socket */ /* close state client socket */
lxc_list_del(cur); list_del(&client->head);
close(client->clientfd); close(client->clientfd);
free(cur->elem); free(client);
free(cur);
} }
if (handler->conf->ephemeral == 1 && handler->conf->reboot != REBOOT_REQ) if (handler->conf->ephemeral == 1 && handler->conf->reboot != REBOOT_REQ)