]>
Commit | Line | Data |
---|---|---|
cc73685d | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
940ef906 | 2 | |
1160ce89 CB |
3 | #include "config.h" |
4 | ||
940ef906 CB |
5 | #include <errno.h> |
6 | #include <fcntl.h> | |
5e97c3fc | 7 | #include <stdio.h> |
12a50cc6 | 8 | #include <stdlib.h> |
0ad19a3f | 9 | #include <string.h> |
940ef906 | 10 | #include <sys/file.h> |
0ad19a3f | 11 | #include <sys/param.h> |
940ef906 | 12 | #include <sys/socket.h> |
0ad19a3f | 13 | #include <sys/stat.h> |
940ef906 | 14 | #include <sys/types.h> |
d38dd64a CB |
15 | #include <time.h> |
16 | #include <unistd.h> | |
5e97c3fc | 17 | |
f2363e38 | 18 | #include "cgroup.h" |
e98fe68b | 19 | #include "commands.h" |
92e35018 | 20 | #include "commands_utils.h" |
940ef906 CB |
21 | #include "log.h" |
22 | #include "lxc.h" | |
23 | #include "monitor.h" | |
24 | #include "start.h" | |
89aca5a5 | 25 | #include "utils.h" |
36eb9bde | 26 | |
ac2cecc4 | 27 | lxc_log_define(state, lxc); |
0ad19a3f | 28 | |
d39b10eb CB |
29 | static const char *const strstate[] = { |
30 | "STOPPED", "STARTING", "RUNNING", "STOPPING", | |
31 | "ABORTING", "FREEZING", "FROZEN", "THAWED", | |
0ad19a3f | 32 | }; |
33 | ||
34 | const char *lxc_state2str(lxc_state_t state) | |
35 | { | |
36 | if (state < STOPPED || state > MAX_STATE - 1) | |
89420aff | 37 | return "INVALID STATE"; |
0ad19a3f | 38 | return strstate[state]; |
39 | } | |
5e97c3fc | 40 | |
0ad19a3f | 41 | lxc_state_t lxc_str2state(const char *state) |
5e97c3fc | 42 | { |
e6a19d26 | 43 | size_t len; |
d594790c CB |
44 | |
45 | len = sizeof(strstate) / sizeof(strstate[0]); | |
46 | for (lxc_state_t i = 0; i < len; i++) { | |
47 | if (strequal(strstate[i], state)) | |
0ad19a3f | 48 | return i; |
d594790c | 49 | } |
3ab87b66 | 50 | |
439358bf | 51 | ERROR("invalid state '%s'", state); |
0ad19a3f | 52 | return -1; |
5e97c3fc | 53 | } |
54 | ||
13f5be62 | 55 | lxc_state_t lxc_getstate(const char *name, const char *lxcpath) |
0ad19a3f | 56 | { |
dd66700c | 57 | return lxc_cmd_get_state(name, lxcpath); |
0ad19a3f | 58 | } |
e98fe68b | 59 | |
dbc9832d | 60 | static int fillwaitedstates(const char *strstates, lxc_state_t *states) |
72d0e1cb | 61 | { |
89aca5a5 CB |
62 | char *token; |
63 | char *strstates_dup; | |
72d0e1cb SG |
64 | int state; |
65 | ||
89aca5a5 | 66 | strstates_dup = strdup(strstates); |
12a50cc6 DE |
67 | if (!strstates_dup) |
68 | return -1; | |
69 | ||
89aca5a5 | 70 | lxc_iterate_parts(token, strstates_dup, "|") { |
72d0e1cb | 71 | state = lxc_str2state(token); |
12a50cc6 DE |
72 | if (state < 0) { |
73 | free(strstates_dup); | |
72d0e1cb | 74 | return -1; |
12a50cc6 | 75 | } |
72d0e1cb SG |
76 | |
77 | states[state] = 1; | |
72d0e1cb | 78 | } |
12a50cc6 | 79 | free(strstates_dup); |
72d0e1cb SG |
80 | return 0; |
81 | } | |
82 | ||
746559f4 CB |
83 | int lxc_wait(const char *lxcname, const char *states, int timeout, |
84 | const char *lxcpath) | |
72d0e1cb | 85 | { |
b695eea2 | 86 | int state = -1; |
dbc9832d | 87 | lxc_state_t s[MAX_STATE] = {0}; |
72d0e1cb SG |
88 | |
89 | if (fillwaitedstates(states, s)) | |
90 | return -1; | |
91 | ||
f577e061 | 92 | for (;;) { |
746559f4 CB |
93 | struct timespec onesec = { |
94 | .tv_sec = 1, | |
95 | .tv_nsec = 0, | |
96 | }; | |
97 | ||
f577e061 CB |
98 | state = lxc_cmd_sock_get_state(lxcname, lxcpath, s, timeout); |
99 | if (state >= 0) | |
100 | break; | |
101 | ||
d2bab66f CB |
102 | if (errno != ECONNREFUSED) |
103 | return log_error_errno(-1, errno, "Failed to receive state from monitor"); | |
f577e061 | 104 | |
f577e061 CB |
105 | if (timeout > 0) |
106 | timeout--; | |
107 | ||
108 | if (timeout == 0) | |
109 | return -1; | |
974a8aba | 110 | |
746559f4 | 111 | (void)nanosleep(&onesec, NULL); |
dbc9832d | 112 | } |
aa460476 | 113 | |
f577e061 | 114 | TRACE("Retrieved state of container %s", lxc_state2str(state)); |
0072919d | 115 | if ((state < STOPPED || state > MAX_STATE - 1) || !s[state]) |
aa460476 CB |
116 | return -1; |
117 | ||
dbc9832d | 118 | return 0; |
72d0e1cb | 119 | } |