2
* lxc: linux Container library
4
* (C) Copyright IBM Corp. 2007, 2008
7
* Daniel Lezcano <dlezcano at fr.ibm.com>
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU Lesser General Public
11
* License as published by the Free Software Foundation; either
12
* version 2.1 of the License, or (at your option) any later version.
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* Lesser General Public License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
#include <sys/types.h>
29
#include <sys/socket.h>
30
#include <sys/param.h>
35
#include <lxc/start.h>
36
#include <lxc/cgroup.h>
40
lxc_log_define(lxc_state, lxc);
42
static char *strstate[] = {
43
"STOPPED", "STARTING", "RUNNING", "STOPPING",
44
"ABORTING", "FREEZING", "FROZEN", "THAWED",
47
const char *lxc_state2str(lxc_state_t state)
49
if (state < STOPPED || state > MAX_STATE - 1)
51
return strstate[state];
54
lxc_state_t lxc_str2state(const char *state)
57
len = sizeof(strstate)/sizeof(strstate[0]);
58
for (i = 0; i < len; i++)
59
if (!strcmp(strstate[i], state))
62
ERROR("invalid state '%s'", state);
66
static int freezer_state(const char *name)
69
char freezer[MAXPATHLEN];
70
char status[MAXPATHLEN];
74
err = lxc_cgroup_path_get(&nsgroup, "freezer", name);
78
err = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup);
79
if (err < 0 || err >= MAXPATHLEN)
82
file = fopen(freezer, "r");
86
err = fscanf(file, "%s", status);
90
SYSERROR("failed to read %s", freezer);
94
return lxc_str2state(status);
97
static lxc_state_t __lxc_getstate(const char *name)
99
struct lxc_command command = {
100
.request = { .type = LXC_COMMAND_STATE },
103
int ret, stopped = 0;
105
ret = lxc_command(name, &command, &stopped);
106
if (ret < 0 && stopped)
110
ERROR("failed to send command");
115
WARN("'%s' has stopped before sending its state", name);
119
if (command.answer.ret < 0) {
120
ERROR("failed to get state for '%s': %s",
121
name, strerror(-command.answer.ret));
125
DEBUG("'%s' is in '%s' state", name, lxc_state2str(command.answer.ret));
127
return command.answer.ret;
130
lxc_state_t lxc_getstate(const char *name)
132
int state = freezer_state(name);
133
if (state != FROZEN && state != FREEZING)
134
state = __lxc_getstate(name);
138
/*----------------------------------------------------------------------------
139
* functions used by lxc-start mainloop
140
* to handle above command request.
141
*--------------------------------------------------------------------------*/
142
extern int lxc_state_callback(int fd, struct lxc_request *request,
143
struct lxc_handler *handler)
145
struct lxc_answer answer;
148
answer.ret = handler->state;
150
ret = send(fd, &answer, sizeof(answer), 0);
152
WARN("failed to send answer to the peer");
156
if (ret != sizeof(answer)) {
157
ERROR("partial answer sent");