Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
b07d3445
Unverified
Commit
b07d3445
authored
Oct 22, 2017
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
commands: non-functional changes
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
51d1ec4f
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
180 additions
and
192 deletions
+180
-192
commands.c
src/lxc/commands.c
+180
-192
No files found.
src/lxc/commands.c
View file @
b07d3445
...
@@ -21,53 +21,54 @@
...
@@ -21,53 +21,54 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
*/
#include <stdio.h>
#include "config.h"
#include <errno.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <fcntl.h>
#include <malloc.h>
#include <poll.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/un.h>
#include <sys/param.h>
#include <malloc.h>
#include <stdlib.h>
#include "log.h"
#include "af_unix.h"
#include "lxc.h"
#include "conf.h"
#include "start.h"
/* for struct lxc_handler */
#include "utils.h"
#include "cgroup.h"
#include "cgroup.h"
#include "commands.h"
#include "commands.h"
#include "commands_utils.h"
#include "commands_utils.h"
#include "con
sole
.h"
#include "con
f
.h"
#include "confile.h"
#include "confile.h"
#include "console.h"
#include "log.h"
#include "lxc.h"
#include "lxclock.h"
#include "lxclock.h"
#include "mainloop.h"
#include "mainloop.h"
#include "monitor.h"
#include "monitor.h"
#include "
af_unix
.h"
#include "
start
.h"
#include "
config
.h"
#include "
utils
.h"
/*
/*
* This file provides the different functions for clients to
* This file provides the different functions for clients to
query/command the
*
query/command the server. The client is typically some lxc
*
server. The client is typically some lxc tool and the server is typically the
*
tool and the server is typically the
container (ie. lxc-start).
* container (ie. lxc-start).
*
*
* Each command is transactional, the clients send a request to
* Each command is transactional, the clients send a request to
the server and
* the server an
d the server answers the request with a message
* the server an
swers the request with a message giving the request's status
*
giving the request's status (zero or a negative errno value).
*
(zero or a negative errno value). Both the request and response may contain
*
Both the request and response may contain
additional data.
* additional data.
*
*
* Each command is wrapped in a ancillary message in order to pass
* Each command is wrapped in a ancillary message in order to pass
a credential
*
a credential making possible to the server to check if the client
*
making possible to the server to check if the client is allowed to ask for
*
is allowed to ask for
this command or not.
* this command or not.
*
*
* IMPORTANTLY: Note that semantics for current commands are fixed.
If you
* IMPORTANTLY: Note that semantics for current commands are fixed.
If you wish
*
wish to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by
*
to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
*
adding
information to the end of cmd.data, then you must introduce a new
* information to the end of cmd.data, then you must introduce a new
* LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number.
You may wish t
o
* LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number.
You may wish to als
o
*
also
mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
* mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
*
*
* This is necessary in order to avoid having a newly compiled lxc command
* This is necessary in order to avoid having a newly compiled lxc command
* communicating with a running (old) monitor from crashing the running
* communicating with a running (old) monitor from crashing the running
...
@@ -78,7 +79,7 @@ lxc_log_define(lxc_commands, lxc);
...
@@ -78,7 +79,7 @@ lxc_log_define(lxc_commands, lxc);
static
const
char
*
lxc_cmd_str
(
lxc_cmd_t
cmd
)
static
const
char
*
lxc_cmd_str
(
lxc_cmd_t
cmd
)
{
{
static
const
char
*
const
cmdname
[
LXC_CMD_MAX
]
=
{
static
const
char
*
const
cmdname
[
LXC_CMD_MAX
]
=
{
[
LXC_CMD_CONSOLE
]
=
"console"
,
[
LXC_CMD_CONSOLE
]
=
"console"
,
[
LXC_CMD_CONSOLE_WINCH
]
=
"console_winch"
,
[
LXC_CMD_CONSOLE_WINCH
]
=
"console_winch"
,
[
LXC_CMD_STOP
]
=
"stop"
,
[
LXC_CMD_STOP
]
=
"stop"
,
...
@@ -94,6 +95,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
...
@@ -94,6 +95,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
if
(
cmd
>=
LXC_CMD_MAX
)
if
(
cmd
>=
LXC_CMD_MAX
)
return
"Unknown cmd"
;
return
"Unknown cmd"
;
return
cmdname
[
cmd
];
return
cmdname
[
cmd
];
}
}
...
@@ -121,11 +123,11 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
...
@@ -121,11 +123,11 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
ret
=
lxc_abstract_unix_recv_fds
(
sock
,
&
rspfd
,
1
,
rsp
,
sizeof
(
*
rsp
));
ret
=
lxc_abstract_unix_recv_fds
(
sock
,
&
rspfd
,
1
,
rsp
,
sizeof
(
*
rsp
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
WARN
(
"
Command %s failed to receive response: %s.
"
,
WARN
(
"
%s - Failed to receive response for command
\"
%s
\"
"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
strerror
(
errno
));
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
));
return
-
1
;
return
-
1
;
}
}
TRACE
(
"Command
\"
%s received response"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
));
TRACE
(
"Command
\"
%s
\"
received response"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
));
if
(
cmd
->
req
.
cmd
==
LXC_CMD_CONSOLE
)
{
if
(
cmd
->
req
.
cmd
==
LXC_CMD_CONSOLE
)
{
struct
lxc_cmd_console_rsp_data
*
rspdata
;
struct
lxc_cmd_console_rsp_data
*
rspdata
;
...
@@ -138,9 +140,9 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
...
@@ -138,9 +140,9 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
rspdata
=
malloc
(
sizeof
(
*
rspdata
));
rspdata
=
malloc
(
sizeof
(
*
rspdata
));
if
(
!
rspdata
)
{
if
(
!
rspdata
)
{
ERROR
(
"
Command %s couldn't allocate response buffer.
"
,
ERROR
(
"
Failed to allocate response buffer for command
\"
%s
\"
"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
));
lxc_cmd_str
(
cmd
->
req
.
cmd
));
return
-
1
;
return
-
ENOMEM
;
}
}
rspdata
->
masterfd
=
rspfd
;
rspdata
->
masterfd
=
rspfd
;
rspdata
->
ttynum
=
PTR_TO_INT
(
rsp
->
data
);
rspdata
->
ttynum
=
PTR_TO_INT
(
rsp
->
data
);
...
@@ -148,26 +150,30 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
...
@@ -148,26 +150,30 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
}
}
if
(
rsp
->
datalen
==
0
)
{
if
(
rsp
->
datalen
==
0
)
{
DEBUG
(
"
command %s response data length
is 0"
,
DEBUG
(
"
Response data length for command
\"
%s
\"
is 0"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
));
lxc_cmd_str
(
cmd
->
req
.
cmd
));
return
ret
;
return
ret
;
}
}
if
(
rsp
->
datalen
>
LXC_CMD_DATA_MAX
)
{
if
(
rsp
->
datalen
>
LXC_CMD_DATA_MAX
)
{
ERROR
(
"Command %s response data %d too long."
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
rsp
->
datalen
);
errno
=
EFBIG
;
errno
=
EFBIG
;
return
-
1
;
ERROR
(
"%s - Response data for command
\"
%s
\"
is too long: %d "
"bytes > %d"
,
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
),
rsp
->
datalen
,
LXC_CMD_DATA_MAX
);
return
-
EFBIG
;
}
}
rsp
->
data
=
malloc
(
rsp
->
datalen
);
rsp
->
data
=
malloc
(
rsp
->
datalen
);
if
(
!
rsp
->
data
)
{
if
(
!
rsp
->
data
)
{
ERROR
(
"Command %s was unable to allocate response buffer."
,
errno
=
ENOMEM
;
lxc_cmd_str
(
cmd
->
req
.
cmd
));
ERROR
(
"%s - Failed to allocate response buffer for command "
return
-
1
;
"
\"
%s
\"
"
,
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
));
return
-
ENOMEM
;
}
}
ret
=
recv
(
sock
,
rsp
->
data
,
rsp
->
datalen
,
0
);
ret
=
recv
(
sock
,
rsp
->
data
,
rsp
->
datalen
,
0
);
if
(
ret
!=
rsp
->
datalen
)
{
if
(
ret
!=
rsp
->
datalen
)
{
ERROR
(
"
Command %s failed to receive response data: %s.
"
,
ERROR
(
"
%s - Failed to receive response data for command
\"
%s
\"
"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
strerror
(
errno
));
lxc_cmd_str
(
cmd
->
req
.
cmd
),
strerror
(
errno
));
if
(
ret
>=
0
)
if
(
ret
>=
0
)
ret
=
-
1
;
ret
=
-
1
;
...
@@ -186,23 +192,25 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
...
@@ -186,23 +192,25 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
*/
*/
static
int
lxc_cmd_rsp_send
(
int
fd
,
struct
lxc_cmd_rsp
*
rsp
)
static
int
lxc_cmd_rsp_send
(
int
fd
,
struct
lxc_cmd_rsp
*
rsp
)
{
{
in
t
ret
;
ssize_
t
ret
;
ret
=
send
(
fd
,
rsp
,
sizeof
(
*
rsp
),
0
);
ret
=
send
(
fd
,
rsp
,
sizeof
(
*
rsp
),
0
);
if
(
ret
!=
sizeof
(
*
rsp
))
{
if
(
ret
<
0
||
(
size_t
)
ret
!=
sizeof
(
*
rsp
))
{
ERROR
(
"
Failed to send command response %d: %s."
,
ret
,
ERROR
(
"
%s - Failed to send command response %zd"
,
strerror
(
errno
));
strerror
(
errno
)
,
ret
);
return
-
1
;
return
-
1
;
}
}
if
(
rsp
->
datalen
>
0
)
{
if
(
rsp
->
datalen
<=
0
)
return
0
;
ret
=
send
(
fd
,
rsp
->
data
,
rsp
->
datalen
,
0
);
ret
=
send
(
fd
,
rsp
->
data
,
rsp
->
datalen
,
0
);
if
(
ret
!=
rsp
->
datalen
)
{
if
(
ret
<
0
||
ret
!=
(
ssize_t
)
rsp
->
datalen
)
{
WARN
(
"Failed to send command response data %d: %s.
"
,
WARN
(
"%s - Failed to send command response data %zd
"
,
ret
,
strerror
(
errno
)
);
strerror
(
errno
),
ret
);
return
-
1
;
return
-
1
;
}
}
}
return
0
;
return
0
;
}
}
...
@@ -210,19 +218,19 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
...
@@ -210,19 +218,19 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
const
char
*
lxcpath
,
const
char
*
hashed_sock_name
)
const
char
*
lxcpath
,
const
char
*
hashed_sock_name
)
{
{
int
client_fd
;
int
client_fd
;
in
t
ret
=
-
1
;
ssize_
t
ret
=
-
1
;
client_fd
=
lxc_cmd_connect
(
name
,
lxcpath
,
hashed_sock_name
);
client_fd
=
lxc_cmd_connect
(
name
,
lxcpath
,
hashed_sock_name
);
if
(
client_fd
<
0
&&
client_fd
==
-
ECONNREFUSED
)
if
(
client_fd
<
0
)
{
if
(
client_fd
==
-
ECONNREFUSED
)
return
-
ECONNREFUSED
;
return
-
ECONNREFUSED
;
else
if
(
client_fd
<
0
)
return
-
1
;
TRACE
(
"Command
\"
%s
\"
connected to command socket"
,
return
-
1
;
lxc_cmd_str
(
cmd
->
req
.
cmd
));
}
ret
=
lxc_abstract_unix_send_credential
(
client_fd
,
&
cmd
->
req
,
sizeof
(
cmd
->
req
));
ret
=
lxc_abstract_unix_send_credential
(
client_fd
,
&
cmd
->
req
,
if
(
ret
!=
sizeof
(
cmd
->
req
))
{
sizeof
(
cmd
->
req
));
if
(
ret
<
0
||
(
size_t
)
ret
!=
sizeof
(
cmd
->
req
))
{
close
(
client_fd
);
close
(
client_fd
);
if
(
errno
==
EPIPE
)
if
(
errno
==
EPIPE
)
...
@@ -234,12 +242,11 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
...
@@ -234,12 +242,11 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
return
-
1
;
return
-
1
;
}
}
TRACE
(
"Command
\"
%s
\"
requested data of length %d"
,
if
(
cmd
->
req
.
datalen
<=
0
)
lxc_cmd_str
(
cmd
->
req
.
cmd
),
cmd
->
req
.
datalen
)
;
return
client_fd
;
if
(
cmd
->
req
.
datalen
>
0
)
{
ret
=
send
(
client_fd
,
cmd
->
req
.
data
,
cmd
->
req
.
datalen
,
MSG_NOSIGNAL
);
ret
=
send
(
client_fd
,
cmd
->
req
.
data
,
cmd
->
req
.
datalen
,
MSG_NOSIGNAL
);
if
(
ret
!=
cmd
->
req
.
datalen
)
{
if
(
ret
<
0
||
ret
!=
(
ssize_t
)
cmd
->
req
.
datalen
)
{
close
(
client_fd
);
close
(
client_fd
);
if
(
errno
==
EPIPE
)
if
(
errno
==
EPIPE
)
...
@@ -250,7 +257,6 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
...
@@ -250,7 +257,6 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
return
-
1
;
return
-
1
;
}
}
}
return
client_fd
;
return
client_fd
;
}
}
...
@@ -277,7 +283,8 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
...
@@ -277,7 +283,8 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
static
int
lxc_cmd
(
const
char
*
name
,
struct
lxc_cmd_rr
*
cmd
,
int
*
stopped
,
static
int
lxc_cmd
(
const
char
*
name
,
struct
lxc_cmd_rr
*
cmd
,
int
*
stopped
,
const
char
*
lxcpath
,
const
char
*
hashed_sock_name
)
const
char
*
lxcpath
,
const
char
*
hashed_sock_name
)
{
{
int
client_fd
,
ret
=
-
1
;
int
client_fd
;
int
ret
=
-
1
;
bool
stay_connected
=
false
;
bool
stay_connected
=
false
;
if
(
cmd
->
req
.
cmd
==
LXC_CMD_CONSOLE
||
if
(
cmd
->
req
.
cmd
==
LXC_CMD_CONSOLE
||
...
@@ -286,13 +293,10 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
...
@@ -286,13 +293,10 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
*
stopped
=
0
;
*
stopped
=
0
;
TRACE
(
"command %s tries to connect command socket"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
));
client_fd
=
lxc_cmd_send
(
name
,
cmd
,
lxcpath
,
hashed_sock_name
);
client_fd
=
lxc_cmd_send
(
name
,
cmd
,
lxcpath
,
hashed_sock_name
);
if
(
client_fd
<
0
)
{
if
(
client_fd
<
0
)
{
TRACE
(
"
command %s failed to connect command socket: %s
"
,
TRACE
(
"
%s - Command
\"
%s
\"
failed to connect command socket
"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
strerror
(
errno
));
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
));
if
(
client_fd
==
-
ECONNREFUSED
)
{
if
(
client_fd
==
-
ECONNREFUSED
)
{
*
stopped
=
1
;
*
stopped
=
1
;
return
-
1
;
return
-
1
;
...
@@ -308,6 +312,7 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
...
@@ -308,6 +312,7 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
out:
out:
if
(
!
stay_connected
||
ret
<=
0
)
if
(
!
stay_connected
||
ret
<=
0
)
close
(
client_fd
);
close
(
client_fd
);
if
(
stay_connected
&&
ret
>
0
)
if
(
stay_connected
&&
ret
>
0
)
cmd
->
rsp
.
ret
=
client_fd
;
cmd
->
rsp
.
ret
=
client_fd
;
...
@@ -326,7 +331,6 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
...
@@ -326,7 +331,6 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
};
};
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
stopped
)
if
(
stopped
)
return
0
;
return
0
;
if
(
ret
>
0
&&
cmd
.
rsp
.
ret
<
0
)
{
if
(
ret
>
0
&&
cmd
.
rsp
.
ret
<
0
)
{
...
@@ -336,14 +340,11 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
...
@@ -336,14 +340,11 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
if
(
ret
>
0
)
if
(
ret
>
0
)
return
0
;
return
0
;
/*
/* At this point we weren't denied access, and the container *was*
* At this point we weren't denied access, and the
* started. There was some inexplicable error in the protocol. I'm not
* container *was* started. There was some inexplicable
* clear on whether we should return -1 here, but we didn't receive a
* error in the protocol.
* -EACCES, so technically it's not that we're not allowed to control
* I'm not clear on whether we should return -1 here, but
* the container - it's just not behaving.
* we didn't receive a -EACCES, so technically it's not that
* we're not allowed to control the container - it's just not
* behaving.
*/
*/
return
0
;
return
0
;
}
}
...
@@ -429,31 +430,20 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
...
@@ -429,31 +430,20 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
struct
lxc_cmd_rr
cmd
=
{
struct
lxc_cmd_rr
cmd
=
{
.
req
=
{
.
req
=
{
.
cmd
=
LXC_CMD_GET_CGROUP
,
.
cmd
=
LXC_CMD_GET_CGROUP
,
.
datalen
=
strlen
(
subsystem
)
+
1
,
.
datalen
=
strlen
(
subsystem
)
+
1
,
.
data
=
subsystem
,
.
data
=
subsystem
,
},
},
};
};
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
TRACE
(
"command %s failed for container
\"
%s
\"
: %s."
,
lxc_cmd_str
(
cmd
.
req
.
cmd
),
name
,
strerror
(
errno
));
return
NULL
;
return
NULL
;
}
if
(
!
ret
)
{
if
(
ret
==
0
)
WARN
(
"container
\"
%s
\"
has stopped before sending its state"
,
name
);
return
NULL
;
return
NULL
;
}
if
(
cmd
.
rsp
.
ret
<
0
||
cmd
.
rsp
.
datalen
<
0
)
{
if
(
cmd
.
rsp
.
ret
<
0
||
cmd
.
rsp
.
datalen
<
0
)
ERROR
(
"command %s failed for container
\"
%s
\"
: %s"
,
lxc_cmd_str
(
cmd
.
req
.
cmd
),
name
,
strerror
(
-
cmd
.
rsp
.
ret
));
return
NULL
;
return
NULL
;
}
TRACE
(
"command %s successful for container
\"
%s
\"
"
,
lxc_cmd_str
(
cmd
.
req
.
cmd
),
name
);
return
cmd
.
rsp
.
data
;
return
cmd
.
rsp
.
data
;
}
}
...
@@ -461,8 +451,8 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
...
@@ -461,8 +451,8 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
static
int
lxc_cmd_get_cgroup_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
static
int
lxc_cmd_get_cgroup_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
struct
lxc_cmd_rsp
rsp
;
const
char
*
path
;
const
char
*
path
;
struct
lxc_cmd_rsp
rsp
;
if
(
req
->
datalen
<
1
)
if
(
req
->
datalen
<
1
)
return
-
1
;
return
-
1
;
...
@@ -470,9 +460,10 @@ static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
...
@@ -470,9 +460,10 @@ static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
path
=
cgroup_get_cgroup
(
handler
,
req
->
data
);
path
=
cgroup_get_cgroup
(
handler
,
req
->
data
);
if
(
!
path
)
if
(
!
path
)
return
-
1
;
return
-
1
;
rsp
.
datalen
=
strlen
(
path
)
+
1
,
rsp
.
data
=
(
char
*
)
path
;
rsp
.
ret
=
0
;
rsp
.
ret
=
0
;
rsp
.
datalen
=
strlen
(
path
)
+
1
;
rsp
.
data
=
(
char
*
)
path
;
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
}
...
@@ -494,7 +485,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item,
...
@@ -494,7 +485,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item,
struct
lxc_cmd_rr
cmd
=
{
struct
lxc_cmd_rr
cmd
=
{
.
req
=
{
.
cmd
=
LXC_CMD_GET_CONFIG_ITEM
,
.
req
=
{
.
cmd
=
LXC_CMD_GET_CONFIG_ITEM
,
.
data
=
item
,
.
data
=
item
,
.
datalen
=
strlen
(
item
)
+
1
,
.
datalen
=
strlen
(
item
)
+
1
,
},
},
};
};
...
@@ -504,6 +495,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item,
...
@@ -504,6 +495,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item,
if
(
cmd
.
rsp
.
ret
==
0
)
if
(
cmd
.
rsp
.
ret
==
0
)
return
cmd
.
rsp
.
data
;
return
cmd
.
rsp
.
data
;
return
NULL
;
return
NULL
;
}
}
...
@@ -511,9 +503,9 @@ static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
...
@@ -511,9 +503,9 @@ static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
int
cilen
;
int
cilen
;
struct
lxc_cmd_rsp
rsp
;
char
*
cidata
;
char
*
cidata
;
struct
lxc_config_t
*
item
;
struct
lxc_config_t
*
item
;
struct
lxc_cmd_rsp
rsp
;
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
item
=
lxc_getconfig
(
req
->
data
);
item
=
lxc_getconfig
(
req
->
data
);
...
@@ -526,6 +518,7 @@ static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
...
@@ -526,6 +518,7 @@ static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
cidata
=
alloca
(
cilen
+
1
);
cidata
=
alloca
(
cilen
+
1
);
if
(
item
->
get
(
req
->
data
,
cidata
,
cilen
+
1
,
handler
->
conf
)
!=
cilen
)
if
(
item
->
get
(
req
->
data
,
cidata
,
cilen
+
1
,
handler
->
conf
)
!=
cilen
)
goto
err1
;
goto
err1
;
cidata
[
cilen
]
=
'\0'
;
cidata
[
cilen
]
=
'\0'
;
rsp
.
data
=
cidata
;
rsp
.
data
=
cidata
;
rsp
.
datalen
=
cilen
+
1
;
rsp
.
datalen
=
cilen
+
1
;
...
@@ -561,12 +554,13 @@ int lxc_cmd_get_state(const char *name, const char *lxcpath)
...
@@ -561,12 +554,13 @@ int lxc_cmd_get_state(const char *name, const char *lxcpath)
return
-
1
;
return
-
1
;
if
(
!
ret
)
{
if
(
!
ret
)
{
WARN
(
"Container
\"
%s
\"
has stopped before sending its state
.
"
,
name
);
WARN
(
"Container
\"
%s
\"
has stopped before sending its state"
,
name
);
return
-
1
;
return
-
1
;
}
}
DEBUG
(
"Container
\"
%s
\"
is in
\"
%s
\"
state
.
"
,
name
,
DEBUG
(
"Container
\"
%s
\"
is in
\"
%s
\"
state"
,
name
,
lxc_state2str
(
PTR_TO_INT
(
cmd
.
rsp
.
data
)));
lxc_state2str
(
PTR_TO_INT
(
cmd
.
rsp
.
data
)));
return
PTR_TO_INT
(
cmd
.
rsp
.
data
);
return
PTR_TO_INT
(
cmd
.
rsp
.
data
);
}
}
...
@@ -597,22 +591,23 @@ int lxc_cmd_stop(const char *name, const char *lxcpath)
...
@@ -597,22 +591,23 @@ int lxc_cmd_stop(const char *name, const char *lxcpath)
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
if
(
stopped
)
{
if
(
stopped
)
{
INFO
(
"Container
\"
%s
\"
is already stopped
.
"
,
name
);
INFO
(
"Container
\"
%s
\"
is already stopped"
,
name
);
return
0
;
return
0
;
}
}
return
-
1
;
return
-
1
;
}
}
/*
w
e do not expect any answer, because we wait for the connection to be
/*
W
e do not expect any answer, because we wait for the connection to be
* closed
* closed
.
*/
*/
if
(
ret
>
0
)
{
if
(
ret
>
0
)
{
ERROR
(
"
Failed to stop container
\"
%s
\"
: %s."
,
name
,
ERROR
(
"
%s - Failed to stop container
\"
%s
\"
"
,
strerror
(
-
cmd
.
rsp
.
ret
));
strerror
(
-
cmd
.
rsp
.
ret
)
,
name
);
return
-
1
;
return
-
1
;
}
}
INFO
(
"Container
\"
%s
\"
has stopped
.
"
,
name
);
INFO
(
"Container
\"
%s
\"
has stopped"
,
name
);
return
0
;
return
0
;
}
}
...
@@ -627,14 +622,15 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
...
@@ -627,14 +622,15 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
rsp
.
ret
=
kill
(
handler
->
pid
,
stopsignal
);
rsp
.
ret
=
kill
(
handler
->
pid
,
stopsignal
);
if
(
!
rsp
.
ret
)
{
if
(
!
rsp
.
ret
)
{
/*
w
e can't just use lxc_unfreeze() since we are already in the
/*
W
e can't just use lxc_unfreeze() since we are already in the
* context of handling the STOP cmd in lxc-start, and calling
* context of handling the STOP cmd in lxc-start, and calling
* lxc_unfreeze() would do another cmd (GET_CGROUP) which would
* lxc_unfreeze() would do another cmd (GET_CGROUP) which would
* deadlock us
* deadlock us
.
*/
*/
if
(
cgroup_unfreeze
(
handler
))
if
(
cgroup_unfreeze
(
handler
))
return
0
;
return
0
;
ERROR
(
"Failed to unfreeze container
\"
%s
\"
."
,
handler
->
name
);
ERROR
(
"Failed to unfreeze container
\"
%s
\"
"
,
handler
->
name
);
rsp
.
ret
=
-
1
;
rsp
.
ret
=
-
1
;
}
}
...
@@ -669,6 +665,7 @@ static int lxc_cmd_console_winch_callback(int fd, struct lxc_cmd_req *req,
...
@@ -669,6 +665,7 @@ static int lxc_cmd_console_winch_callback(int fd, struct lxc_cmd_req *req,
struct
lxc_cmd_rsp
rsp
=
{
.
data
=
0
};
struct
lxc_cmd_rsp
rsp
=
{
.
data
=
0
};
lxc_console_sigwinch
(
SIGWINCH
);
lxc_console_sigwinch
(
SIGWINCH
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
}
...
@@ -696,27 +693,28 @@ int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
...
@@ -696,27 +693,28 @@ int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
return
ret
;
return
ret
;
if
(
cmd
.
rsp
.
ret
<
0
)
{
if
(
cmd
.
rsp
.
ret
<
0
)
{
ERROR
(
"
Console access denied: %s.
"
,
strerror
(
-
cmd
.
rsp
.
ret
));
ERROR
(
"
%s - Denied access to tty
"
,
strerror
(
-
cmd
.
rsp
.
ret
));
ret
=
-
1
;
ret
=
-
1
;
goto
out
;
goto
out
;
}
}
if
(
ret
==
0
)
{
if
(
ret
==
0
)
{
ERROR
(
"
Console %d invalid, busy or all consoles busy.
"
,
*
ttynum
);
ERROR
(
"
tty number %d invalid, busy or all ttys busy
"
,
*
ttynum
);
ret
=
-
1
;
ret
=
-
1
;
goto
out
;
goto
out
;
}
}
rspdata
=
cmd
.
rsp
.
data
;
rspdata
=
cmd
.
rsp
.
data
;
if
(
rspdata
->
masterfd
<
0
)
{
if
(
rspdata
->
masterfd
<
0
)
{
ERROR
(
"Unable to allocate fd for tty %d
.
"
,
rspdata
->
ttynum
);
ERROR
(
"Unable to allocate fd for tty %d"
,
rspdata
->
ttynum
);
goto
out
;
goto
out
;
}
}
ret
=
cmd
.
rsp
.
ret
;
/* sock
fd */
ret
=
cmd
.
rsp
.
ret
;
/* socket
fd */
*
fd
=
rspdata
->
masterfd
;
*
fd
=
rspdata
->
masterfd
;
*
ttynum
=
rspdata
->
ttynum
;
*
ttynum
=
rspdata
->
ttynum
;
INFO
(
"tty %d allocated fd %d sock %d."
,
rspdata
->
ttynum
,
*
fd
,
ret
);
INFO
(
"Alloced fd %d for tty %d via socket %d"
,
*
fd
,
rspdata
->
ttynum
,
ret
);
out:
out:
free
(
cmd
.
rsp
.
data
);
free
(
cmd
.
rsp
.
data
);
return
ret
;
return
ret
;
...
@@ -725,9 +723,9 @@ out:
...
@@ -725,9 +723,9 @@ out:
static
int
lxc_cmd_console_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
static
int
lxc_cmd_console_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
int
ttynum
=
PTR_TO_INT
(
req
->
data
);
int
masterfd
,
ret
;
int
masterfd
;
struct
lxc_cmd_rsp
rsp
;
struct
lxc_cmd_rsp
rsp
;
int
ttynum
=
PTR_TO_INT
(
req
->
data
);
masterfd
=
lxc_console_allocate
(
handler
->
conf
,
fd
,
&
ttynum
);
masterfd
=
lxc_console_allocate
(
handler
->
conf
,
fd
,
&
ttynum
);
if
(
masterfd
<
0
)
if
(
masterfd
<
0
)
...
@@ -735,8 +733,9 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
...
@@ -735,8 +733,9 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
rsp
.
data
=
INT_TO_PTR
(
ttynum
);
rsp
.
data
=
INT_TO_PTR
(
ttynum
);
if
(
lxc_abstract_unix_send_fds
(
fd
,
&
masterfd
,
1
,
&
rsp
,
sizeof
(
rsp
))
<
0
)
{
ret
=
lxc_abstract_unix_send_fds
(
fd
,
&
masterfd
,
1
,
&
rsp
,
sizeof
(
rsp
));
ERROR
(
"Failed to send tty to client."
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to send tty to client"
);
lxc_console_free
(
handler
->
conf
,
fd
);
lxc_console_free
(
handler
->
conf
,
fd
);
goto
out_close
;
goto
out_close
;
}
}
...
@@ -744,8 +743,8 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
...
@@ -744,8 +743,8 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
return
0
;
return
0
;
out_close:
out_close:
/*
s
pecial indicator to lxc_cmd_handler() to close the fd and do
/*
S
pecial indicator to lxc_cmd_handler() to close the fd and do
* related cleanup
* related cleanup
.
*/
*/
return
1
;
return
1
;
}
}
...
@@ -765,12 +764,12 @@ char *lxc_cmd_get_name(const char *hashed_sock_name)
...
@@ -765,12 +764,12 @@ char *lxc_cmd_get_name(const char *hashed_sock_name)
};
};
ret
=
lxc_cmd
(
NULL
,
&
cmd
,
&
stopped
,
NULL
,
hashed_sock_name
);
ret
=
lxc_cmd
(
NULL
,
&
cmd
,
&
stopped
,
NULL
,
hashed_sock_name
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
return
NULL
;
return
NULL
;
}
if
(
cmd
.
rsp
.
ret
==
0
)
if
(
cmd
.
rsp
.
ret
==
0
)
return
cmd
.
rsp
.
data
;
return
cmd
.
rsp
.
data
;
return
NULL
;
return
NULL
;
}
}
...
@@ -803,12 +802,12 @@ char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
...
@@ -803,12 +802,12 @@ char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
};
};
ret
=
lxc_cmd
(
NULL
,
&
cmd
,
&
stopped
,
NULL
,
hashed_sock_name
);
ret
=
lxc_cmd
(
NULL
,
&
cmd
,
&
stopped
,
NULL
,
hashed_sock_name
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
return
NULL
;
return
NULL
;
}
if
(
cmd
.
rsp
.
ret
==
0
)
if
(
cmd
.
rsp
.
ret
==
0
)
return
cmd
.
rsp
.
data
;
return
cmd
.
rsp
.
data
;
return
NULL
;
return
NULL
;
}
}
...
@@ -819,9 +818,9 @@ static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
...
@@ -819,9 +818,9 @@ static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
memset
(
&
rsp
,
0
,
sizeof
(
rsp
));
rsp
.
ret
=
0
;
rsp
.
data
=
(
char
*
)
handler
->
lxcpath
;
rsp
.
data
=
(
char
*
)
handler
->
lxcpath
;
rsp
.
datalen
=
strlen
(
handler
->
lxcpath
)
+
1
;
rsp
.
datalen
=
strlen
(
handler
->
lxcpath
)
+
1
;
rsp
.
ret
=
0
;
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
}
...
@@ -849,53 +848,49 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
...
@@ -849,53 +848,49 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
state
=
lxc_getstate
(
name
,
lxcpath
);
state
=
lxc_getstate
(
name
,
lxcpath
);
if
(
state
<
0
)
{
if
(
state
<
0
)
{
process_unlock
();
process_unlock
();
TRACE
(
"failed to retrieve state of container: %s"
,
TRACE
(
"%s - Failed to retrieve state of container"
,
strerror
(
errno
));
strerror
(
errno
));
return
-
1
;
return
-
1
;
}
else
if
(
states
[
state
])
{
}
else
if
(
states
[
state
])
{
process_unlock
();
process_unlock
();
TRACE
(
"
c
ontainer is %s state"
,
lxc_state2str
(
state
));
TRACE
(
"
C
ontainer is %s state"
,
lxc_state2str
(
state
));
return
state
;
return
state
;
}
}
if
((
state
==
STARTING
)
&&
!
states
[
RUNNING
]
&&
!
states
[
STOPPING
]
&&
!
states
[
STOPPED
])
{
if
((
state
==
STARTING
)
&&
!
states
[
RUNNING
]
&&
!
states
[
STOPPING
]
&&
!
states
[
STOPPED
])
{
process_unlock
();
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
TRACE
(
"Container is in %s state and caller requested to be "
"informed about a previous state"
,
"informed about a previous state"
,
lxc_state2str
(
state
));
lxc_state2str
(
state
));
return
state
;
return
state
;
}
else
if
((
state
==
RUNNING
)
&&
!
states
[
STOPPING
]
&&
!
states
[
STOPPED
])
{
}
else
if
((
state
==
RUNNING
)
&&
!
states
[
STOPPING
]
&&
!
states
[
STOPPED
])
{
process_unlock
();
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
TRACE
(
"Container is in %s state and caller requested to be "
"informed about a previous state"
,
"informed about a previous state"
,
lxc_state2str
(
state
));
lxc_state2str
(
state
));
return
state
;
return
state
;
}
else
if
((
state
==
STOPPING
)
&&
!
states
[
STOPPED
])
{
}
else
if
((
state
==
STOPPING
)
&&
!
states
[
STOPPED
])
{
process_unlock
();
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
TRACE
(
"Container is in %s state and caller requested to be "
"informed about a previous state"
,
"informed about a previous state"
,
lxc_state2str
(
state
));
lxc_state2str
(
state
));
return
state
;
return
state
;
}
else
if
((
state
==
STOPPED
)
||
(
state
==
ABORTING
))
{
}
else
if
((
state
==
STOPPED
)
||
(
state
==
ABORTING
))
{
process_unlock
();
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
TRACE
(
"Container is in %s state and caller requested to be "
"informed about a previous state"
,
"informed about a previous state"
,
lxc_state2str
(
state
));
lxc_state2str
(
state
));
return
state
;
return
state
;
}
}
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
process_unlock
();
process_unlock
();
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"
failed to execute command: %s
"
,
strerror
(
errno
));
ERROR
(
"
%s - Failed to execute command
"
,
strerror
(
errno
));
return
-
1
;
return
-
1
;
}
}
/* We should now be guaranteed to get an answer from the state sending
/* We should now be guaranteed to get an answer from the state sending
* function.
* function.
*/
*/
if
(
cmd
.
rsp
.
ret
<
0
)
{
if
(
cmd
.
rsp
.
ret
<
0
)
{
ERROR
(
"
f
ailed to receive socket fd"
);
ERROR
(
"
F
ailed to receive socket fd"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -908,20 +903,14 @@ static int lxc_cmd_add_state_client_callback(int fd, struct lxc_cmd_req *req,
...
@@ -908,20 +903,14 @@ static int lxc_cmd_add_state_client_callback(int fd, struct lxc_cmd_req *req,
{
{
struct
lxc_cmd_rsp
rsp
=
{
0
};
struct
lxc_cmd_rsp
rsp
=
{
0
};
if
(
req
->
datalen
<
0
)
{
if
(
req
->
datalen
<
0
)
TRACE
(
"Requested datalen was < 0"
);
return
-
1
;
return
-
1
;
}
if
(
req
->
datalen
>
(
sizeof
(
lxc_state_t
)
*
MAX_STATE
))
{
if
(
req
->
datalen
>
(
sizeof
(
lxc_state_t
)
*
MAX_STATE
))
TRACE
(
"Requested datalen was too large"
);
return
-
1
;
return
-
1
;
}
if
(
!
req
->
data
)
{
if
(
!
req
->
data
)
TRACE
(
"No states requested"
);
return
-
1
;
return
-
1
;
}
rsp
.
ret
=
lxc_add_state_client
(
fd
,
handler
,
(
lxc_state_t
*
)
req
->
data
);
rsp
.
ret
=
lxc_add_state_client
(
fd
,
handler
,
(
lxc_state_t
*
)
req
->
data
);
if
(
rsp
.
ret
<
0
)
if
(
rsp
.
ret
<
0
)
...
@@ -952,7 +941,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
...
@@ -952,7 +941,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
};
};
if
(
req
->
cmd
>=
LXC_CMD_MAX
)
{
if
(
req
->
cmd
>=
LXC_CMD_MAX
)
{
ERROR
(
"Undefined command id %d
received.
"
,
req
->
cmd
);
ERROR
(
"Undefined command id %d"
,
req
->
cmd
);
return
-
1
;
return
-
1
;
}
}
return
cb
[
req
->
cmd
](
fd
,
req
,
handler
);
return
cb
[
req
->
cmd
](
fd
,
req
,
handler
);
...
@@ -975,38 +964,34 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
...
@@ -975,38 +964,34 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
ret
=
lxc_abstract_unix_rcv_credential
(
fd
,
&
req
,
sizeof
(
req
));
ret
=
lxc_abstract_unix_rcv_credential
(
fd
,
&
req
,
sizeof
(
req
));
if
(
ret
==
-
EACCES
)
{
if
(
ret
==
-
EACCES
)
{
/*
we don't care for the peer, just send and close
*/
/*
We don't care for the peer, just send and close.
*/
struct
lxc_cmd_rsp
rsp
=
{
.
ret
=
ret
};
struct
lxc_cmd_rsp
rsp
=
{
.
ret
=
ret
};
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
goto
out_close
;
goto
out_close
;
}
}
TRACE
(
"Processing
\"
%s
\"
command"
,
lxc_cmd_str
(
req
.
cmd
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to receive data on command socket for
\"
%s
\"
"
,
SYSERROR
(
"Failed to receive data on command socket for
command "
lxc_cmd_str
(
req
.
cmd
));
"
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
goto
out_close
;
goto
out_close
;
}
}
if
(
!
ret
)
{
if
(
ret
==
0
)
DEBUG
(
"Peer has disconnected for
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
goto
out_close
;
goto
out_close
;
}
if
(
ret
!=
sizeof
(
req
))
{
if
(
ret
!=
sizeof
(
req
))
{
WARN
(
"Failed to receive full command request. Ignoring request "
WARN
(
"Failed to receive full command request. Ignoring request "
"for
\"
%s
\"
"
,
"for
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
lxc_cmd_str
(
req
.
cmd
));
ret
=
-
1
;
ret
=
-
1
;
goto
out_close
;
goto
out_close
;
}
}
if
(
req
.
datalen
>
LXC_CMD_DATA_MAX
)
{
if
(
req
.
datalen
>
LXC_CMD_DATA_MAX
)
{
ERROR
(
"Received command data length %d is too large for "
ERROR
(
"Received command data length %d is too large for "
"command
\"
%s
\"
"
,
"command
\"
%s
\"
"
,
req
.
datalen
,
lxc_cmd_str
(
req
.
cmd
));
req
.
datalen
,
lxc_cmd_str
(
req
.
cmd
))
;
errno
=
EFBIG
;
ret
=
-
1
;
ret
=
-
EFBIG
;
goto
out_close
;
goto
out_close
;
}
}
...
@@ -1017,23 +1002,24 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
...
@@ -1017,23 +1002,24 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
ret
=
recv
(
fd
,
reqdata
,
req
.
datalen
,
0
);
ret
=
recv
(
fd
,
reqdata
,
req
.
datalen
,
0
);
if
(
ret
!=
req
.
datalen
)
{
if
(
ret
!=
req
.
datalen
)
{
WARN
(
"Failed to receive full command request. Ignoring "
WARN
(
"Failed to receive full command request. Ignoring "
"request for
\"
%s
\"
"
,
"request for
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
lxc_cmd_str
(
req
.
cmd
));
ret
=
-
1
;
ret
=
-
1
;
goto
out_close
;
goto
out_close
;
}
}
req
.
data
=
reqdata
;
req
.
data
=
reqdata
;
}
}
ret
=
lxc_cmd_process
(
fd
,
&
req
,
handler
);
ret
=
lxc_cmd_process
(
fd
,
&
req
,
handler
);
if
(
ret
)
{
if
(
ret
)
{
/*
this is not an error, but only a request to close fd
*/
/*
This is not an error, but only a request to close fd.
*/
ret
=
0
;
ret
=
0
;
goto
out_close
;
goto
out_close
;
}
}
out:
out:
return
ret
;
return
ret
;
out_close:
out_close:
lxc_cmd_fd_cleanup
(
fd
,
handler
,
descr
);
lxc_cmd_fd_cleanup
(
fd
,
handler
,
descr
);
goto
out
;
goto
out
;
...
@@ -1042,7 +1028,8 @@ out_close:
...
@@ -1042,7 +1028,8 @@ out_close:
static
int
lxc_cmd_accept
(
int
fd
,
uint32_t
events
,
void
*
data
,
static
int
lxc_cmd_accept
(
int
fd
,
uint32_t
events
,
void
*
data
,
struct
lxc_epoll_descr
*
descr
)
struct
lxc_epoll_descr
*
descr
)
{
{
int
opt
=
1
,
ret
=
-
1
,
connection
;
int
connection
;
int
opt
=
1
,
ret
=
-
1
;
connection
=
accept
(
fd
,
NULL
,
0
);
connection
=
accept
(
fd
,
NULL
,
0
);
if
(
connection
<
0
)
{
if
(
connection
<
0
)
{
...
@@ -1050,20 +1037,21 @@ static int lxc_cmd_accept(int fd, uint32_t events, void *data,
...
@@ -1050,20 +1037,21 @@ static int lxc_cmd_accept(int fd, uint32_t events, void *data,
return
-
1
;
return
-
1
;
}
}
if
(
fcntl
(
connection
,
F_SETFD
,
FD_CLOEXEC
))
{
ret
=
fcntl
(
connection
,
F_SETFD
,
FD_CLOEXEC
);
SYSERROR
(
"Failed to set close-on-exec on incoming command connection."
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set close-on-exec on incoming command connection"
);
goto
out_close
;
goto
out_close
;
}
}
if
(
setsockopt
(
connection
,
SOL_SOCKET
,
ret
=
setsockopt
(
connection
,
SOL_SOCKET
,
SO_PASSCRED
,
&
opt
,
sizeof
(
opt
));
SO_PASSCRED
,
&
opt
,
sizeof
(
opt
))
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to enable necessary credentials on command socket
.
"
);
SYSERROR
(
"Failed to enable necessary credentials on command socket"
);
goto
out_close
;
goto
out_close
;
}
}
ret
=
lxc_mainloop_add_handler
(
descr
,
connection
,
lxc_cmd_handler
,
data
);
ret
=
lxc_mainloop_add_handler
(
descr
,
connection
,
lxc_cmd_handler
,
data
);
if
(
ret
)
{
if
(
ret
)
{
ERROR
(
"Failed to add command handler
.
"
);
ERROR
(
"Failed to add command handler"
);
goto
out_close
;
goto
out_close
;
}
}
...
@@ -1078,10 +1066,9 @@ out_close:
...
@@ -1078,10 +1066,9 @@ out_close:
int
lxc_cmd_init
(
const
char
*
name
,
struct
lxc_handler
*
handler
,
int
lxc_cmd_init
(
const
char
*
name
,
struct
lxc_handler
*
handler
,
const
char
*
lxcpath
)
const
char
*
lxcpath
)
{
{
int
fd
;
int
fd
,
len
,
ret
;
char
path
[
sizeof
(((
struct
sockaddr_un
*
)
0
)
->
sun_path
)]
=
{
0
};
char
path
[
sizeof
(((
struct
sockaddr_un
*
)
0
)
->
sun_path
)]
=
{
0
};
char
*
offset
=
&
path
[
1
];
char
*
offset
=
&
path
[
1
];
int
len
;
/* -2 here because this is an abstract unix socket so it needs a
/* -2 here because this is an abstract unix socket so it needs a
* leading \0, and we null terminate, so it needs a trailing \0.
* leading \0, and we null terminate, so it needs a trailing \0.
...
@@ -1089,21 +1076,22 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
...
@@ -1089,21 +1076,22 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
* because we print the sockname out sometimes.
* because we print the sockname out sometimes.
*/
*/
len
=
sizeof
(
path
)
-
2
;
len
=
sizeof
(
path
)
-
2
;
if
(
lxc_make_abstract_socket_name
(
offset
,
len
,
name
,
lxcpath
,
NULL
,
ret
=
lxc_make_abstract_socket_name
(
offset
,
len
,
name
,
lxcpath
,
NULL
,
"command"
);
"command"
)
)
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
fd
=
lxc_abstract_unix_open
(
path
,
SOCK_STREAM
,
0
);
fd
=
lxc_abstract_unix_open
(
path
,
SOCK_STREAM
,
0
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
ERROR
(
"
Failed to create the command service point %s: %s.
"
,
ERROR
(
"
%s - Failed to create command socket %s
"
,
offset
,
strerror
(
errno
)
);
strerror
(
errno
),
offset
);
if
(
errno
==
EADDRINUSE
)
if
(
errno
==
EADDRINUSE
)
ERROR
(
"Container
\"
%s
\"
appears to be already running
!
"
,
name
);
ERROR
(
"Container
\"
%s
\"
appears to be already running"
,
name
);
return
-
1
;
return
-
1
;
}
}
if
(
fcntl
(
fd
,
F_SETFD
,
FD_CLOEXEC
))
{
ret
=
fcntl
(
fd
,
F_SETFD
,
FD_CLOEXEC
);
SYSERROR
(
"Failed to set FD_CLOEXEC on signal file descriptor."
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set FD_CLOEXEC on command socket file descriptor"
);
close
(
fd
);
close
(
fd
);
return
-
1
;
return
-
1
;
}
}
...
@@ -1112,15 +1100,15 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
...
@@ -1112,15 +1100,15 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
return
0
;
return
0
;
}
}
int
lxc_cmd_mainloop_add
(
const
char
*
name
,
int
lxc_cmd_mainloop_add
(
const
char
*
name
,
struct
lxc_epoll_descr
*
descr
,
struct
lxc_epoll_descr
*
descr
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
int
ret
,
fd
=
handler
->
conf
->
maincmd_fd
;
int
ret
;
int
fd
=
handler
->
conf
->
maincmd_fd
;
ret
=
lxc_mainloop_add_handler
(
descr
,
fd
,
lxc_cmd_accept
,
handler
);
ret
=
lxc_mainloop_add_handler
(
descr
,
fd
,
lxc_cmd_accept
,
handler
);
if
(
ret
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to add handler for command socket
.
"
);
ERROR
(
"Failed to add handler for command socket"
);
close
(
fd
);
close
(
fd
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment