]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/state.c
state: convert to strequal()
[mirror_lxc.git] / src / lxc / state.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef _GNU_SOURCE
4 #define _GNU_SOURCE 1
5 #endif
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/file.h>
12 #include <sys/param.h>
13 #include <sys/socket.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include <time.h>
17 #include <unistd.h>
18
19 #include "cgroup.h"
20 #include "commands.h"
21 #include "commands_utils.h"
22 #include "config.h"
23 #include "log.h"
24 #include "lxc.h"
25 #include "monitor.h"
26 #include "start.h"
27 #include "utils.h"
28
29 lxc_log_define(state, lxc);
30
31 static const char *const strstate[] = {
32 "STOPPED", "STARTING", "RUNNING", "STOPPING",
33 "ABORTING", "FREEZING", "FROZEN", "THAWED",
34 };
35
36 const char *lxc_state2str(lxc_state_t state)
37 {
38 if (state < STOPPED || state > MAX_STATE - 1)
39 return NULL;
40 return strstate[state];
41 }
42
43 lxc_state_t lxc_str2state(const char *state)
44 {
45 size_t len;
46
47 len = sizeof(strstate) / sizeof(strstate[0]);
48 for (lxc_state_t i = 0; i < len; i++) {
49 if (strequal(strstate[i], state))
50 return i;
51 }
52
53 ERROR("invalid state '%s'", state);
54 return -1;
55 }
56
57 lxc_state_t lxc_getstate(const char *name, const char *lxcpath)
58 {
59 return lxc_cmd_get_state(name, lxcpath);
60 }
61
62 static int fillwaitedstates(const char *strstates, lxc_state_t *states)
63 {
64 char *token;
65 char *strstates_dup;
66 int state;
67
68 strstates_dup = strdup(strstates);
69 if (!strstates_dup)
70 return -1;
71
72 lxc_iterate_parts(token, strstates_dup, "|") {
73 state = lxc_str2state(token);
74 if (state < 0) {
75 free(strstates_dup);
76 return -1;
77 }
78
79 states[state] = 1;
80 }
81 free(strstates_dup);
82 return 0;
83 }
84
85 int lxc_wait(const char *lxcname, const char *states, int timeout,
86 const char *lxcpath)
87 {
88 int state = -1;
89 lxc_state_t s[MAX_STATE] = {0};
90
91 if (fillwaitedstates(states, s))
92 return -1;
93
94 for (;;) {
95 struct timespec onesec = {
96 .tv_sec = 1,
97 .tv_nsec = 0,
98 };
99
100 state = lxc_cmd_sock_get_state(lxcname, lxcpath, s, timeout);
101 if (state >= 0)
102 break;
103
104 if (errno != ECONNREFUSED)
105 return log_error_errno(-1, errno, "Failed to receive state from monitor");
106
107 if (timeout > 0)
108 timeout--;
109
110 if (timeout == 0)
111 return -1;
112
113 (void)nanosleep(&onesec, NULL);
114 }
115
116 TRACE("Retrieved state of container %s", lxc_state2str(state));
117 if (!s[state])
118 return -1;
119
120 return 0;
121 }