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
87b7179c
Unverified
Commit
87b7179c
authored
Dec 11, 2018
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
commands: backport robust infrastructure
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
c458e212
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
145 additions
and
129 deletions
+145
-129
commands.c
src/lxc/commands.c
+102
-102
commands.h
src/lxc/commands.h
+12
-4
commands_utils.c
src/lxc/commands_utils.c
+29
-22
commands_utils.h
src/lxc/commands_utils.h
+2
-1
No files found.
src/lxc/commands.c
View file @
87b7179c
...
@@ -21,8 +21,10 @@
...
@@ -21,8 +21,10 @@
* 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 "config.h"
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <caps.h>
#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <malloc.h>
#include <malloc.h>
...
@@ -30,16 +32,17 @@
...
@@ -30,16 +32,17 @@
#include <signal.h>
#include <signal.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/un.h>
#include <unistd.h>
#include "af_unix.h"
#include "af_unix.h"
#include "cgroup.h"
#include "cgroup.h"
#include "commands.h"
#include "commands.h"
#include "commands_utils.h"
#include "commands_utils.h"
#include "conf.h"
#include "conf.h"
#include "config.h"
#include "confile.h"
#include "confile.h"
#include "console.h"
#include "console.h"
#include "log.h"
#include "log.h"
...
@@ -96,7 +99,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
...
@@ -96,7 +99,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
"
Invalid request
"
;
return
cmdname
[
cmd
];
return
cmdname
[
cmd
];
}
}
...
@@ -125,10 +128,11 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
...
@@ -125,10 +128,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
(
"%s - Failed to receive response for command
\"
%s
\"
"
,
SYSWARN
(
"Failed to receive response for command
\"
%s
\"
"
,
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
));
lxc_cmd_str
(
cmd
->
req
.
cmd
));
if
(
errno
==
ECONNRESET
)
if
(
errno
==
ECONNRESET
)
return
-
ECONNRESET
;
return
-
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -145,10 +149,12 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
...
@@ -145,10 +149,12 @@ 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
)
{
errno
=
ENOMEM
;
ERROR
(
"Failed to allocate response buffer for command
\"
%s
\"
"
,
ERROR
(
"Failed to allocate response buffer for command
\"
%s
\"
"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
));
lxc_cmd_str
(
cmd
->
req
.
cmd
));
return
-
ENOMEM
;
return
-
1
;
}
}
rspdata
->
masterfd
=
rspfd
;
rspdata
->
masterfd
=
rspfd
;
rspdata
->
ttynum
=
PTR_TO_INT
(
rsp
->
data
);
rspdata
->
ttynum
=
PTR_TO_INT
(
rsp
->
data
);
rsp
->
data
=
rspdata
;
rsp
->
data
=
rspdata
;
...
@@ -161,27 +167,24 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
...
@@ -161,27 +167,24 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
}
}
if
(
rsp
->
datalen
>
LXC_CMD_DATA_MAX
)
{
if
(
rsp
->
datalen
>
LXC_CMD_DATA_MAX
)
{
errno
=
EFBIG
;
ERROR
(
"Response data for command
\"
%s
\"
is too long: %d bytes > %d"
,
ERROR
(
"%s - Response data for command
\"
%s
\"
is too long: %d "
lxc_cmd_str
(
cmd
->
req
.
cmd
),
rsp
->
datalen
,
LXC_CMD_DATA_MAX
);
"bytes > %d"
,
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
),
return
-
1
;
rsp
->
datalen
,
LXC_CMD_DATA_MAX
);
return
-
EFBIG
;
}
}
rsp
->
data
=
malloc
(
rsp
->
datalen
);
rsp
->
data
=
malloc
(
rsp
->
datalen
);
if
(
!
rsp
->
data
)
{
if
(
!
rsp
->
data
)
{
errno
=
ENOMEM
;
errno
=
ENOMEM
;
ERROR
(
"
%s - Failed to allocate response buffer for command "
ERROR
(
"
Failed to allocate response buffer for command
\"
%s
\"
"
,
"
\"
%s
\"
"
,
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
));
lxc_cmd_str
(
cmd
->
req
.
cmd
));
return
-
ENOMEM
;
return
-
1
;
}
}
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
(
"%s - Failed to receive response data for command
\"
%s
\"
"
,
SYSERROR
(
"Failed to receive response data for command
\"
%s
\"
"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
strerror
(
errno
));
lxc_cmd_str
(
cmd
->
req
.
cmd
));
if
(
ret
>=
0
)
return
-
1
;
ret
=
-
1
;
}
}
return
ret
;
return
ret
;
...
@@ -199,20 +202,19 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
...
@@ -199,20 +202,19 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
{
{
ssize_t
ret
;
ssize_t
ret
;
ret
=
send
(
fd
,
rsp
,
sizeof
(
*
rsp
),
0
);
errno
=
EMSGSIZE
;
ret
=
send
(
fd
,
rsp
,
sizeof
(
*
rsp
),
MSG_NOSIGNAL
);
if
(
ret
<
0
||
(
size_t
)
ret
!=
sizeof
(
*
rsp
))
{
if
(
ret
<
0
||
(
size_t
)
ret
!=
sizeof
(
*
rsp
))
{
ERROR
(
"%s - Failed to send command response %zd"
,
SYSERROR
(
"Failed to send command response %zd"
,
ret
);
strerror
(
errno
),
ret
);
return
-
1
;
return
-
1
;
}
}
if
(
!
rsp
->
data
||
rsp
->
datalen
<=
0
)
if
(
!
rsp
->
data
||
rsp
->
datalen
<=
0
)
return
0
;
return
0
;
ret
=
send
(
fd
,
rsp
->
data
,
rsp
->
datalen
,
0
);
ret
=
send
(
fd
,
rsp
->
data
,
rsp
->
datalen
,
MSG_NOSIGNAL
);
if
(
ret
<
0
||
ret
!=
(
ssize_t
)
rsp
->
datalen
)
{
if
(
ret
<
0
||
ret
!=
(
ssize_t
)
rsp
->
datalen
)
{
WARN
(
"%s - Failed to send command response data %zd"
,
SYSWARN
(
"Failed to send command response data %zd"
,
ret
);
strerror
(
errno
),
ret
);
return
-
1
;
return
-
1
;
}
}
...
@@ -222,48 +224,35 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
...
@@ -222,48 +224,35 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
static
int
lxc_cmd_send
(
const
char
*
name
,
struct
lxc_cmd_rr
*
cmd
,
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
,
saved_errno
;
ssize_t
ret
=
-
1
;
ssize_t
ret
=
-
1
;
client_fd
=
lxc_cmd_connect
(
name
,
lxcpath
,
hashed_sock_name
,
"command"
);
client_fd
=
lxc_cmd_connect
(
name
,
lxcpath
,
hashed_sock_name
,
"command"
);
if
(
client_fd
<
0
)
{
if
(
client_fd
<
0
)
if
(
client_fd
==
-
ECONNREFUSED
)
return
-
ECONNREFUSED
;
return
-
1
;
return
-
1
;
}
ret
=
lxc_abstract_unix_send_credential
(
client_fd
,
&
cmd
->
req
,
ret
=
lxc_abstract_unix_send_credential
(
client_fd
,
&
cmd
->
req
,
sizeof
(
cmd
->
req
));
sizeof
(
cmd
->
req
));
if
(
ret
<
0
||
(
size_t
)
ret
!=
sizeof
(
cmd
->
req
))
{
if
(
ret
<
0
||
(
size_t
)
ret
!=
sizeof
(
cmd
->
req
))
close
(
client_fd
);
goto
on_error
;
if
(
errno
==
EPIPE
)
return
-
EPIPE
;
if
(
ret
>=
0
)
return
-
EMSGSIZE
;
return
-
1
;
}
if
(
cmd
->
req
.
datalen
<=
0
)
if
(
cmd
->
req
.
datalen
<=
0
)
return
client_fd
;
return
client_fd
;
ret
=
send
(
client_fd
,
cmd
->
req
.
data
,
cmd
->
req
.
datalen
,
MSG_NOSIGNAL
);
errno
=
EMSGSIZE
;
if
(
ret
<
0
||
ret
!=
(
ssize_t
)
cmd
->
req
.
datalen
)
{
ret
=
send
(
client_fd
,
(
void
*
)
cmd
->
req
.
data
,
cmd
->
req
.
datalen
,
close
(
client_fd
);
MSG_NOSIGNAL
);
if
(
ret
<
0
||
ret
!=
(
ssize_t
)
cmd
->
req
.
datalen
)
goto
on_error
;
if
(
errno
==
EPIPE
)
return
client_fd
;
return
-
EPIPE
;
if
(
ret
>=
0
)
return
-
EMSGSIZE
;
return
-
1
;
on_error:
}
saved_errno
=
errno
;
close
(
client_fd
);
errno
=
saved_errno
;
return
client_fd
;
return
-
1
;
}
}
/*
/*
...
@@ -288,7 +277,7 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
...
@@ -288,7 +277,7 @@ 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
;
int
client_fd
,
saved_errno
;
int
ret
=
-
1
;
int
ret
=
-
1
;
bool
stay_connected
=
false
;
bool
stay_connected
=
false
;
...
@@ -300,27 +289,25 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
...
@@ -300,27 +289,25 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
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
(
"%s - Command
\"
%s
\"
failed to connect command socket"
,
SYSTRACE
(
"Command
\"
%s
\"
failed to connect command socket"
,
strerror
(
errno
),
lxc_cmd_str
(
cmd
->
req
.
cmd
));
lxc_cmd_str
(
cmd
->
req
.
cmd
));
if
(
client_fd
==
-
ECONNREFUSED
)
*
stopped
=
1
;
if
(
client_fd
==
-
EPIPE
)
{
if
(
errno
==
ECONNREFUSED
||
errno
==
EPIPE
)
*
stopped
=
1
;
*
stopped
=
1
;
client_fd
=
0
;
}
return
client_fd
;
return
-
1
;
}
}
ret
=
lxc_cmd_rsp_recv
(
client_fd
,
cmd
);
ret
=
lxc_cmd_rsp_recv
(
client_fd
,
cmd
);
if
(
ret
==
-
ECONNRESET
)
if
(
ret
<
0
&&
errno
==
ECONNRESET
)
*
stopped
=
1
;
*
stopped
=
1
;
if
(
!
stay_connected
||
ret
<=
0
)
if
(
!
stay_connected
||
ret
<=
0
)
{
if
(
client_fd
>=
0
)
saved_errno
=
errno
;
close
(
client_fd
);
close
(
client_fd
);
errno
=
saved_errno
;
return
ret
;
}
if
(
stay_connected
&&
ret
>
0
)
if
(
stay_connected
&&
ret
>
0
)
cmd
->
rsp
.
ret
=
client_fd
;
cmd
->
rsp
.
ret
=
client_fd
;
...
@@ -354,7 +341,7 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
...
@@ -354,7 +341,7 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
return
0
;
return
0
;
}
}
/* Implentations of the commands and their callbacks */
/* Imple
me
ntations of the commands and their callbacks */
/*
/*
* lxc_cmd_get_init_pid: Get pid of the container's init process
* lxc_cmd_get_init_pid: Get pid of the container's init process
...
@@ -367,21 +354,38 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
...
@@ -367,21 +354,38 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
pid_t
lxc_cmd_get_init_pid
(
const
char
*
name
,
const
char
*
lxcpath
)
pid_t
lxc_cmd_get_init_pid
(
const
char
*
name
,
const
char
*
lxcpath
)
{
{
int
ret
,
stopped
;
int
ret
,
stopped
;
intmax_t
pid
;
struct
lxc_cmd_rr
cmd
=
{
struct
lxc_cmd_rr
cmd
=
{
.
req
=
{
.
cmd
=
LXC_CMD_GET_INIT_PID
},
.
req
=
{
.
cmd
=
LXC_CMD_GET_INIT_PID
},
.
rsp
=
{
.
data
=
INTMAX_TO_PTR
((
intmax_t
){
-
1
})
}
};
};
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
-
1
;
return
PTR_TO_INT
(
cmd
.
rsp
.
data
);
pid
=
PTR_TO_INTMAX
(
cmd
.
rsp
.
data
);
if
(
pid
<
0
)
return
-
1
;
/* We need to assume that pid_t can actually hold any pid given to us
* by the kernel. If it can't it's a libc bug.
*/
return
(
pid_t
)
pid
;
}
}
static
int
lxc_cmd_get_init_pid_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
static
int
lxc_cmd_get_init_pid_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
struct
lxc_cmd_rsp
rsp
=
{
.
data
=
INT_TO_PTR
(
handler
->
pid
)
};
intmax_t
pid
=
handler
->
pid
;
struct
lxc_cmd_rsp
rsp
=
{
.
data
=
INTMAX_TO_PTR
(
pid
)
};
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
}
...
@@ -612,8 +616,8 @@ int lxc_cmd_stop(const char *name, const char *lxcpath)
...
@@ -612,8 +616,8 @@ int lxc_cmd_stop(const char *name, const char *lxcpath)
* closed.
* closed.
*/
*/
if
(
ret
>
0
)
{
if
(
ret
>
0
)
{
ERROR
(
"%s - Failed to stop container
\"
%s
\"
"
,
errno
=
-
cmd
.
rsp
.
ret
;
strerror
(
-
cmd
.
rsp
.
ret
)
,
name
);
SYSERROR
(
"Failed to stop container
\"
%s
\"
"
,
name
);
return
-
1
;
return
-
1
;
}
}
...
@@ -703,7 +707,8 @@ int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
...
@@ -703,7 +707,8 @@ 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
(
"%s - Denied access to tty"
,
strerror
(
-
cmd
.
rsp
.
ret
));
errno
=
-
cmd
.
rsp
.
ret
;
SYSERROR
(
"Denied access to tty"
);
ret
=
-
1
;
ret
=
-
1
;
goto
out
;
goto
out
;
}
}
...
@@ -855,7 +860,8 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
...
@@ -855,7 +860,8 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
if
(
errno
!=
ECONNREFUSED
)
if
(
errno
!=
ECONNREFUSED
)
ERROR
(
"%s - Failed to execute command"
,
strerror
(
errno
));
SYSERROR
(
"Failed to execute command"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -863,7 +869,8 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
...
@@ -863,7 +869,8 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
* function.
* function.
*/
*/
if
(
cmd
.
rsp
.
ret
<
0
)
{
if
(
cmd
.
rsp
.
ret
<
0
)
{
ERROR
(
"%s - Failed to receive socket fd"
,
strerror
(
-
cmd
.
rsp
.
ret
));
errno
=
-
cmd
.
rsp
.
ret
;
SYSERROR
(
"Failed to receive socket fd"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -938,7 +945,7 @@ int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath,
...
@@ -938,7 +945,7 @@ int lxc_cmd_serve_state_clients(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
)
{
ERROR
(
"%s - Failed to execute command"
,
strerror
(
errno
)
);
SYSERROR
(
"Failed to execute command"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -1036,17 +1043,17 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
...
@@ -1036,17 +1043,17 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
struct
lxc_handler
*
handler
=
data
;
struct
lxc_handler
*
handler
=
data
;
ret
=
lxc_abstract_unix_rcv_credential
(
fd
,
&
req
,
sizeof
(
req
));
ret
=
lxc_abstract_unix_rcv_credential
(
fd
,
&
req
,
sizeof
(
req
));
if
(
ret
==
-
EACCES
)
{
/* We don't care for the peer, just send and close. */
struct
lxc_cmd_rsp
rsp
=
{.
ret
=
ret
};
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
goto
out_close
;
}
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to receive data on command socket for command "
SYSERROR
(
"Failed to receive data on command socket for command "
"
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
"
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
if
(
errno
==
EACCES
)
{
/* We don't care for the peer, just send and close. */
struct
lxc_cmd_rsp
rsp
=
{.
ret
=
ret
};
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
goto
out_close
;
goto
out_close
;
}
}
...
@@ -1138,27 +1145,20 @@ out_close:
...
@@ -1138,27 +1145,20 @@ out_close:
int
lxc_cmd_init
(
const
char
*
name
,
const
char
*
lxcpath
,
const
char
*
suffix
)
int
lxc_cmd_init
(
const
char
*
name
,
const
char
*
lxcpath
,
const
char
*
suffix
)
{
{
int
fd
,
len
,
ret
;
int
fd
,
ret
;
char
path
[
sizeof
(((
struct
sockaddr_un
*
)
0
)
->
sun_path
)]
=
{
0
};
char
path
[
LXC_AUDS_ADDR_LEN
]
=
{
0
};
char
*
offset
=
&
path
[
1
];
ret
=
lxc_make_abstract_socket_name
(
path
,
sizeof
(
path
),
name
,
lxcpath
,
NULL
,
suffix
);
/* -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.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
len
=
sizeof
(
path
)
-
2
;
ret
=
lxc_make_abstract_socket_name
(
offset
,
len
,
name
,
lxcpath
,
NULL
,
suffix
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
TRACE
(
"Creating abstract unix socket
\"
%s
\"
"
,
offset
);
TRACE
(
"Creating abstract unix socket
\"
%s
\"
"
,
&
path
[
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
(
"%s - Failed to create command socket %s"
,
SYSERROR
(
"Failed to create command socket %s"
,
&
path
[
1
]);
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
;
}
}
...
...
src/lxc/commands.h
View file @
87b7179c
...
@@ -25,16 +25,24 @@
...
@@ -25,16 +25,24 @@
#define __LXC_COMMANDS_H
#define __LXC_COMMANDS_H
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>
#include "lxccontainer.h"
#include "state.h"
#include "state.h"
#define LXC_CMD_DATA_MAX (MAXPATHLEN * 2)
#define LXC_CMD_DATA_MAX (MAXPATHLEN * 2)
/* https://developer.gnome.org/glib/2.28/glib-Type-Conversion-Macros.html */
/* Length of abstract unix domain socket socket address. */
#define INT_TO_PTR(n) ((void *)(long)(n))
#define LXC_AUDS_ADDR_LEN sizeof(((struct sockaddr_un *)0)->sun_path)
#define PTR_TO_INT(p) ((int)(long)(p))
/* pointer conversion macros */
#define PTR_TO_INT(p) ((int)((intptr_t)(p)))
#define INT_TO_PTR(u) ((void *)((intptr_t)(u)))
#define PTR_TO_INTMAX(p) ((intmax_t)((intptr_t)(p)))
#define INTMAX_TO_PTR(u) ((void *)((intptr_t)(u)))
typedef
enum
{
typedef
enum
{
LXC_CMD_CONSOLE
,
LXC_CMD_CONSOLE
,
...
...
src/lxc/commands_utils.c
View file @
87b7179c
...
@@ -17,20 +17,23 @@
...
@@ -17,20 +17,23 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
*/
#define _GNU_SOURCE
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#define __STDC_FORMAT_MACROS
/* Required for PRIu64 to work. */
#define __STDC_FORMAT_MACROS
/* Required for PRIu64 to work. */
#include <errno.h>
#include <errno.h>
#include <inttypes.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/un.h>
#include <unistd.h>
#include "af_unix.h"
#include "af_unix.h"
#include "commands.h"
#include "commands.h"
#include "commands_utils.h"
#include "commands_utils.h"
#include "config.h"
#include "initutils.h"
#include "initutils.h"
#include "log.h"
#include "log.h"
#include "lxclock.h"
#include "lxclock.h"
...
@@ -52,7 +55,7 @@ int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout)
...
@@ -52,7 +55,7 @@ int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout)
ret
=
setsockopt
(
state_client_fd
,
SOL_SOCKET
,
SO_RCVTIMEO
,
ret
=
setsockopt
(
state_client_fd
,
SOL_SOCKET
,
SO_RCVTIMEO
,
(
const
void
*
)
&
out
,
sizeof
(
out
));
(
const
void
*
)
&
out
,
sizeof
(
out
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set %ds timeout on contain
t
er "
SYSERROR
(
"Failed to set %ds timeout on container "
"state socket"
,
"state socket"
,
timeout
);
timeout
);
return
-
1
;
return
-
1
;
...
@@ -98,24 +101,38 @@ int lxc_cmd_sock_get_state(const char *name, const char *lxcpath,
...
@@ -98,24 +101,38 @@ int lxc_cmd_sock_get_state(const char *name, const char *lxcpath,
return
ret
;
return
ret
;
}
}
int
lxc_make_abstract_socket_name
(
char
*
path
,
int
len
,
const
char
*
lxcname
,
int
lxc_make_abstract_socket_name
(
char
*
path
,
size_t
pathlen
,
const
char
*
lxcname
,
const
char
*
lxcpath
,
const
char
*
lxcpath
,
const
char
*
hashed_sock_name
,
const
char
*
hashed_sock_name
,
const
char
*
suffix
)
const
char
*
suffix
)
{
{
const
char
*
name
;
const
char
*
name
;
char
*
offset
;
char
*
tmppath
;
char
*
tmppath
;
size_t
len
;
size_t
tmplen
;
size_t
tmplen
;
uint64_t
hash
;
uint64_t
hash
;
int
ret
;
int
ret
;
if
(
!
path
)
return
-
1
;
offset
=
&
path
[
1
];
/* -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.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
len
=
pathlen
-
2
;
name
=
lxcname
;
name
=
lxcname
;
if
(
!
name
)
if
(
!
name
)
name
=
""
;
name
=
""
;
if
(
hashed_sock_name
!=
NULL
)
{
if
(
hashed_sock_name
!=
NULL
)
{
ret
=
ret
=
snprintf
(
offset
,
len
,
"lxc/%s/%s"
,
hashed_sock_name
,
suffix
);
snprintf
(
path
,
len
,
"lxc/%s/%s"
,
hashed_sock_name
,
suffix
);
if
(
ret
<
0
||
ret
>=
len
)
{
if
(
ret
<
0
||
ret
>=
len
)
{
ERROR
(
"Failed to create abstract socket name"
);
ERROR
(
"Failed to create abstract socket name"
);
return
-
1
;
return
-
1
;
...
@@ -131,7 +148,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
...
@@ -131,7 +148,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
}
}
}
}
ret
=
snprintf
(
path
,
len
,
"%s/%s/%s"
,
lxcpath
,
name
,
suffix
);
ret
=
snprintf
(
offset
,
len
,
"%s/%s/%s"
,
lxcpath
,
name
,
suffix
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to create abstract socket name"
);
ERROR
(
"Failed to create abstract socket name"
);
return
-
1
;
return
-
1
;
...
@@ -149,7 +166,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
...
@@ -149,7 +166,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
}
}
hash
=
fnv_64a_buf
(
tmppath
,
ret
,
FNV1A_64_INIT
);
hash
=
fnv_64a_buf
(
tmppath
,
ret
,
FNV1A_64_INIT
);
ret
=
snprintf
(
path
,
len
,
"lxc/%016"
PRIx64
"/%s"
,
hash
,
suffix
);
ret
=
snprintf
(
offset
,
len
,
"lxc/%016"
PRIx64
"/%s"
,
hash
,
suffix
);
if
(
ret
<
0
||
ret
>=
len
)
{
if
(
ret
<
0
||
ret
>=
len
)
{
ERROR
(
"Failed to create abstract socket name"
);
ERROR
(
"Failed to create abstract socket name"
);
return
-
1
;
return
-
1
;
...
@@ -162,27 +179,17 @@ int lxc_cmd_connect(const char *name, const char *lxcpath,
...
@@ -162,27 +179,17 @@ int lxc_cmd_connect(const char *name, const char *lxcpath,
const
char
*
hashed_sock_name
,
const
char
*
suffix
)
const
char
*
hashed_sock_name
,
const
char
*
suffix
)
{
{
int
ret
,
client_fd
;
int
ret
,
client_fd
;
char
path
[
sizeof
(((
struct
sockaddr_un
*
)
0
)
->
sun_path
)]
=
{
0
};
char
path
[
LXC_AUDS_ADDR_LEN
]
=
{
0
};
char
*
offset
=
&
path
[
1
];
/* -2 here because this is an abstract unix socket so it needs a
ret
=
lxc_make_abstract_socket_name
(
path
,
sizeof
(
path
),
name
,
lxcpath
,
* leading \0, and we null terminate, so it needs a trailing \0.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
size_t
len
=
sizeof
(
path
)
-
2
;
ret
=
lxc_make_abstract_socket_name
(
offset
,
len
,
name
,
lxcpath
,
hashed_sock_name
,
suffix
);
hashed_sock_name
,
suffix
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
/* Get new client fd. */
/* Get new client fd. */
client_fd
=
lxc_abstract_unix_connect
(
path
);
client_fd
=
lxc_abstract_unix_connect
(
path
);
if
(
client_fd
<
0
)
{
if
(
client_fd
<
0
)
if
(
errno
==
ECONNREFUSED
)
return
-
ECONNREFUSED
;
return
-
1
;
return
-
1
;
}
return
client_fd
;
return
client_fd
;
}
}
...
@@ -218,6 +225,6 @@ int lxc_add_state_client(int state_client_fd, struct lxc_handler *handler,
...
@@ -218,6 +225,6 @@ int lxc_add_state_client(int state_client_fd, struct lxc_handler *handler,
return
state
;
return
state
;
}
}
TRACE
(
"
a
dded state client %d to state client list"
,
state_client_fd
);
TRACE
(
"
A
dded state client %d to state client list"
,
state_client_fd
);
return
MAX_STATE
;
return
MAX_STATE
;
}
}
src/lxc/commands_utils.h
View file @
87b7179c
...
@@ -25,7 +25,8 @@
...
@@ -25,7 +25,8 @@
#include "state.h"
#include "state.h"
#include "commands.h"
#include "commands.h"
int
lxc_make_abstract_socket_name
(
char
*
path
,
int
len
,
const
char
*
lxcname
,
int
lxc_make_abstract_socket_name
(
char
*
path
,
size_t
pathlen
,
const
char
*
lxcname
,
const
char
*
lxcpath
,
const
char
*
lxcpath
,
const
char
*
hashed_sock_name
,
const
char
*
hashed_sock_name
,
const
char
*
suffix
);
const
char
*
suffix
);
...
...
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