Commit 2137dc99 by Daniel Lezcano

handle the stop command

Handle the stop command. The stop command waits for the peer to disconnect, that means the peer has exited, so it is safe to return to the user control. By this way, we ensure a stop command followed by a start or a destroy won't fail with a race condition because the start command is not yet finised. Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: 's avatarMichel Normand <normand@fr.ibm.com>
parent 3cc5de36
...@@ -95,6 +95,8 @@ out_close: ...@@ -95,6 +95,8 @@ out_close:
extern void lxc_console_remove_fd(int fd, struct lxc_tty_info *tty_info); extern void lxc_console_remove_fd(int fd, struct lxc_tty_info *tty_info);
extern int lxc_console_callback(int fd, struct lxc_request *request, extern int lxc_console_callback(int fd, struct lxc_request *request,
struct lxc_handler *handler); struct lxc_handler *handler);
extern int lxc_stop_callback(int fd, struct lxc_request *request,
struct lxc_handler *handler);
static int trigger_command(int fd, struct lxc_request *request, static int trigger_command(int fd, struct lxc_request *request,
struct lxc_handler *handler) struct lxc_handler *handler)
...@@ -104,6 +106,7 @@ static int trigger_command(int fd, struct lxc_request *request, ...@@ -104,6 +106,7 @@ static int trigger_command(int fd, struct lxc_request *request,
callback cb[LXC_COMMAND_MAX] = { callback cb[LXC_COMMAND_MAX] = {
[LXC_COMMAND_TTY] = lxc_console_callback, [LXC_COMMAND_TTY] = lxc_console_callback,
[LXC_COMMAND_STOP] = lxc_stop_callback,
}; };
if (request->type < 0 || request->type >= LXC_COMMAND_MAX) if (request->type < 0 || request->type >= LXC_COMMAND_MAX)
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
enum { enum {
LXC_COMMAND_TTY, LXC_COMMAND_TTY,
LXC_COMMAND_STOP,
LXC_COMMAND_MAX, LXC_COMMAND_MAX,
}; };
......
...@@ -33,12 +33,13 @@ ...@@ -33,12 +33,13 @@
#include <lxc/lxc.h> #include <lxc/lxc.h>
#include <lxc/log.h> #include <lxc/log.h>
#include "commands.h"
lxc_log_define(lxc_stop, lxc); lxc_log_define(lxc_stop, lxc);
#define MAXPIDLEN 20 #define MAXPIDLEN 20
int lxc_stop(const char *name) int __lxc_stop(const char *name)
{ {
char init[MAXPATHLEN]; char init[MAXPATHLEN];
char val[MAXPIDLEN]; char val[MAXPIDLEN];
...@@ -73,3 +74,61 @@ out_close: ...@@ -73,3 +74,61 @@ out_close:
close(fd); close(fd);
return ret; return ret;
} }
int lxc_stop(const char *name)
{
struct lxc_command command = {
.request = { .type = LXC_COMMAND_STOP },
};
int ret;
ret = lxc_command(name, &command);
if (ret < 0) {
ERROR("failed to send command");
return -1;
}
/* we do not expect any answer, because we wait for the connection to be
* closed
*/
if (ret > 0) {
ERROR("stop request rejected for '%s': %s",
name, strerror(-command.answer.ret));
return -1;
}
INFO("'%s' has stopped", name);
return 0;
}
/*----------------------------------------------------------------------------
* functions used by lxc-start mainloop
* to handle above command request.
*--------------------------------------------------------------------------*/
extern int lxc_stop_callback(int fd, struct lxc_request *request,
struct lxc_handler *handler)
{
struct lxc_answer answer;
int ret;
answer.ret = kill(handler->pid, SIGKILL);
if (!answer.ret)
return 0;
ret = send(fd, &answer, sizeof(answer), 0);
if (ret < 0) {
WARN("failed to send answer to the peer");
goto out;
}
if (ret != sizeof(answer)) {
ERROR("partial answer sent");
goto out;
}
out:
return -1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment