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
010a85d1
Unverified
Commit
010a85d1
authored
Jul 21, 2018
by
Christian Brauner
Committed by
GitHub
Jul 21, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2482 from 2xsec/bugfix
error handling cleanups #2471
parents
8fd3e219
9044b79e
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
353 additions
and
125 deletions
+353
-125
af_unix.c
src/lxc/af_unix.c
+18
-13
af_unix.h
src/lxc/af_unix.h
+1
-1
attach.c
src/lxc/attach.c
+12
-3
lxc_monitord.c
src/lxc/cmd/lxc_monitord.c
+45
-31
commands.c
src/lxc/commands.c
+15
-12
confile_utils.c
src/lxc/confile_utils.c
+37
-17
confile_utils.h
src/lxc/confile_utils.h
+1
-1
lxccontainer.c
src/lxc/lxccontainer.c
+209
-41
start.c
src/lxc/start.c
+15
-6
No files found.
src/lxc/af_unix.c
View file @
010a85d1
...
@@ -74,30 +74,28 @@ int lxc_abstract_unix_open(const char *path, int type, int flags)
...
@@ -74,30 +74,28 @@ int lxc_abstract_unix_open(const char *path, int type, int flags)
ret
=
bind
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
ret
=
bind
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
+
1
);
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
+
1
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
int
tmp
=
errno
;
int
saved_erron
=
errno
;
close
(
fd
);
close
(
fd
);
errno
=
tmp
;
errno
=
saved_erron
;
return
-
1
;
return
-
1
;
}
}
if
(
type
==
SOCK_STREAM
)
{
if
(
type
==
SOCK_STREAM
)
{
ret
=
listen
(
fd
,
100
);
ret
=
listen
(
fd
,
100
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
int
tmp
=
errno
;
int
saved_erron
=
errno
;
close
(
fd
);
close
(
fd
);
errno
=
tmp
;
errno
=
saved_erron
;
return
-
1
;
return
-
1
;
}
}
}
}
return
fd
;
return
fd
;
}
}
int
lxc_abstract_unix_close
(
int
fd
)
void
lxc_abstract_unix_close
(
int
fd
)
{
{
close
(
fd
);
close
(
fd
);
return
0
;
}
}
int
lxc_abstract_unix_connect
(
const
char
*
path
)
int
lxc_abstract_unix_connect
(
const
char
*
path
)
...
@@ -128,7 +126,9 @@ int lxc_abstract_unix_connect(const char *path)
...
@@ -128,7 +126,9 @@ int lxc_abstract_unix_connect(const char *path)
ret
=
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
ret
=
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
+
1
);
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
+
1
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
int
saved_errno
=
errno
;
close
(
fd
);
close
(
fd
);
errno
=
saved_errno
;
return
-
1
;
return
-
1
;
}
}
...
@@ -150,8 +150,10 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
...
@@ -150,8 +150,10 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
memset
(
&
iov
,
0
,
sizeof
(
iov
));
memset
(
&
iov
,
0
,
sizeof
(
iov
));
cmsgbuf
=
malloc
(
cmsgbufsize
);
cmsgbuf
=
malloc
(
cmsgbufsize
);
if
(
!
cmsgbuf
)
if
(
!
cmsgbuf
)
{
errno
=
ENOMEM
;
return
-
1
;
return
-
1
;
}
msg
.
msg_control
=
cmsgbuf
;
msg
.
msg_control
=
cmsgbuf
;
msg
.
msg_controllen
=
cmsgbufsize
;
msg
.
msg_controllen
=
cmsgbufsize
;
...
@@ -190,8 +192,10 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
...
@@ -190,8 +192,10 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
memset
(
&
iov
,
0
,
sizeof
(
iov
));
memset
(
&
iov
,
0
,
sizeof
(
iov
));
cmsgbuf
=
malloc
(
cmsgbufsize
);
cmsgbuf
=
malloc
(
cmsgbufsize
);
if
(
!
cmsgbuf
)
if
(
!
cmsgbuf
)
{
errno
=
ENOMEM
;
return
-
1
;
return
-
1
;
}
msg
.
msg_control
=
cmsgbuf
;
msg
.
msg_control
=
cmsgbuf
;
msg
.
msg_controllen
=
cmsgbufsize
;
msg
.
msg_controllen
=
cmsgbufsize
;
...
@@ -209,9 +213,8 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
...
@@ -209,9 +213,8 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
memset
(
recvfds
,
-
1
,
num_recvfds
*
sizeof
(
int
));
memset
(
recvfds
,
-
1
,
num_recvfds
*
sizeof
(
int
));
if
(
cmsg
&&
cmsg
->
cmsg_len
==
CMSG_LEN
(
num_recvfds
*
sizeof
(
int
))
&&
if
(
cmsg
&&
cmsg
->
cmsg_len
==
CMSG_LEN
(
num_recvfds
*
sizeof
(
int
))
&&
cmsg
->
cmsg_level
==
SOL_SOCKET
&&
cmsg
->
cmsg_type
==
SCM_RIGHTS
)
{
cmsg
->
cmsg_level
==
SOL_SOCKET
&&
cmsg
->
cmsg_type
==
SCM_RIGHTS
)
memcpy
(
recvfds
,
CMSG_DATA
(
cmsg
),
num_recvfds
*
sizeof
(
int
));
memcpy
(
recvfds
,
CMSG_DATA
(
cmsg
),
num_recvfds
*
sizeof
(
int
));
}
out:
out:
free
(
cmsgbuf
);
free
(
cmsgbuf
);
...
@@ -281,10 +284,12 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
...
@@ -281,10 +284,12 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
memcpy
(
&
cred
,
CMSG_DATA
(
cmsg
),
sizeof
(
cred
));
memcpy
(
&
cred
,
CMSG_DATA
(
cmsg
),
sizeof
(
cred
));
if
(
cred
.
uid
&&
if
(
cred
.
uid
&&
(
cred
.
uid
!=
getuid
()
||
cred
.
gid
!=
getgid
()))
{
(
cred
.
uid
!=
getuid
()
||
cred
.
gid
!=
getgid
()))
{
INFO
(
"message denied for '%d/%d'"
,
cred
.
uid
,
cred
.
gid
);
INFO
(
"Message denied for '%d/%d'"
,
cred
.
uid
,
cred
.
gid
);
return
-
EACCES
;
errno
=
EACCES
;
return
-
1
;
}
}
}
}
out:
out:
return
ret
;
return
ret
;
}
}
src/lxc/af_unix.h
View file @
010a85d1
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
/* does not enforce \0-termination */
/* does not enforce \0-termination */
extern
int
lxc_abstract_unix_open
(
const
char
*
path
,
int
type
,
int
flags
);
extern
int
lxc_abstract_unix_open
(
const
char
*
path
,
int
type
,
int
flags
);
extern
int
lxc_abstract_unix_close
(
int
fd
);
extern
void
lxc_abstract_unix_close
(
int
fd
);
/* does not enforce \0-termination */
/* does not enforce \0-termination */
extern
int
lxc_abstract_unix_connect
(
const
char
*
path
);
extern
int
lxc_abstract_unix_connect
(
const
char
*
path
);
extern
int
lxc_abstract_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
extern
int
lxc_abstract_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
...
...
src/lxc/attach.c
View file @
010a85d1
...
@@ -828,8 +828,13 @@ static int attach_child_main(struct attach_clone_payload *payload)
...
@@ -828,8 +828,13 @@ static int attach_child_main(struct attach_clone_payload *payload)
*/
*/
if
(
needs_lsm
)
{
if
(
needs_lsm
)
{
ret
=
lxc_abstract_unix_recv_fds
(
payload
->
ipc_socket
,
&
lsm_fd
,
1
,
NULL
,
0
);
ret
=
lxc_abstract_unix_recv_fds
(
payload
->
ipc_socket
,
&
lsm_fd
,
1
,
NULL
,
0
);
if
(
ret
<=
0
)
if
(
ret
<=
0
)
{
if
(
ret
<
0
)
SYSERROR
(
"Failed to receive lsm label fd"
);
goto
on_error
;
goto
on_error
;
}
TRACE
(
"Received LSM label file descriptor %d from parent"
,
lsm_fd
);
TRACE
(
"Received LSM label file descriptor %d from parent"
,
lsm_fd
);
}
}
...
@@ -1330,11 +1335,15 @@ int lxc_attach(const char *name, const char *lxcpath,
...
@@ -1330,11 +1335,15 @@ int lxc_attach(const char *name, const char *lxcpath,
/* Send child fd of the LSM security module to write to. */
/* Send child fd of the LSM security module to write to. */
ret
=
lxc_abstract_unix_send_fds
(
ipc_sockets
[
0
],
&
labelfd
,
1
,
NULL
,
0
);
ret
=
lxc_abstract_unix_send_fds
(
ipc_sockets
[
0
],
&
labelfd
,
1
,
NULL
,
0
);
close
(
labelfd
);
if
(
ret
<=
0
)
{
if
(
ret
<=
0
)
{
SYSERROR
(
"%d"
,
(
int
)
ret
);
if
(
ret
<
0
)
SYSERROR
(
"Failed to send lsm label fd"
);
close
(
labelfd
);
goto
close_mainloop
;
goto
close_mainloop
;
}
}
close
(
labelfd
);
TRACE
(
"Sent LSM label file descriptor %d to child"
,
labelfd
);
TRACE
(
"Sent LSM label file descriptor %d to child"
,
labelfd
);
}
}
...
...
src/lxc/cmd/lxc_monitord.c
View file @
010a85d1
...
@@ -97,8 +97,8 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
...
@@ -97,8 +97,8 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
mon
->
fifofd
=
open
(
fifo_path
,
O_RDWR
);
mon
->
fifofd
=
open
(
fifo_path
,
O_RDWR
);
if
(
mon
->
fifofd
<
0
)
{
if
(
mon
->
fifofd
<
0
)
{
SYSERROR
(
"Failed to open monitor fifo %s"
,
fifo_path
);
unlink
(
fifo_path
);
unlink
(
fifo_path
);
ERROR
(
"Failed to open monitor fifo."
);
return
-
1
;
return
-
1
;
}
}
...
@@ -106,12 +106,14 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
...
@@ -106,12 +106,14 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
lk
.
l_whence
=
SEEK_SET
;
lk
.
l_whence
=
SEEK_SET
;
lk
.
l_start
=
0
;
lk
.
l_start
=
0
;
lk
.
l_len
=
0
;
lk
.
l_len
=
0
;
if
(
fcntl
(
mon
->
fifofd
,
F_SETLK
,
&
lk
)
!=
0
)
{
if
(
fcntl
(
mon
->
fifofd
,
F_SETLK
,
&
lk
)
!=
0
)
{
/* another lxc-monitord is already running, don't start up */
/* another lxc-monitord is already running, don't start up */
DEBUG
(
"lxc-monitord already running on lxcpath %s.
"
,
mon
->
lxcpath
);
SYSDEBUG
(
"lxc-monitord already running on lxcpath %s
"
,
mon
->
lxcpath
);
close
(
mon
->
fifofd
);
close
(
mon
->
fifofd
);
return
-
1
;
return
-
1
;
}
}
return
0
;
return
0
;
}
}
...
@@ -132,15 +134,15 @@ static void lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd) {
...
@@ -132,15 +134,15 @@ static void lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd) {
int
i
;
int
i
;
if
(
lxc_mainloop_del_handler
(
&
mon
->
descr
,
fd
))
if
(
lxc_mainloop_del_handler
(
&
mon
->
descr
,
fd
))
CRIT
(
"File descriptor %d not found in mainloop
.
"
,
fd
);
CRIT
(
"File descriptor %d not found in mainloop"
,
fd
);
close
(
fd
);
close
(
fd
);
for
(
i
=
0
;
i
<
mon
->
clientfds_cnt
;
i
++
)
{
for
(
i
=
0
;
i
<
mon
->
clientfds_cnt
;
i
++
)
if
(
mon
->
clientfds
[
i
]
==
fd
)
if
(
mon
->
clientfds
[
i
]
==
fd
)
break
;
break
;
}
if
(
i
>=
mon
->
clientfds_cnt
)
{
if
(
i
>=
mon
->
clientfds_cnt
)
{
CRIT
(
"File descriptor %d not found in clients array
.
"
,
fd
);
CRIT
(
"File descriptor %d not found in clients array"
,
fd
);
lxc_monitord_cleanup
();
lxc_monitord_cleanup
();
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
...
@@ -166,6 +168,7 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data,
...
@@ -166,6 +168,7 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data,
if
(
events
&
EPOLLHUP
)
if
(
events
&
EPOLLHUP
)
lxc_monitord_sockfd_remove
(
mon
,
fd
);
lxc_monitord_sockfd_remove
(
mon
,
fd
);
return
quit
;
return
quit
;
}
}
...
@@ -180,53 +183,55 @@ static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data,
...
@@ -180,53 +183,55 @@ static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data,
ret
=
LXC_MAINLOOP_ERROR
;
ret
=
LXC_MAINLOOP_ERROR
;
clientfd
=
accept
(
fd
,
NULL
,
0
);
clientfd
=
accept
(
fd
,
NULL
,
0
);
if
(
clientfd
<
0
)
{
if
(
clientfd
<
0
)
{
SYSERROR
(
"Failed to accept connection for client file descriptor %d
.
"
,
fd
);
SYSERROR
(
"Failed to accept connection for client file descriptor %d"
,
fd
);
goto
out
;
goto
out
;
}
}
if
(
fcntl
(
clientfd
,
F_SETFD
,
FD_CLOEXEC
))
{
if
(
fcntl
(
clientfd
,
F_SETFD
,
FD_CLOEXEC
))
{
SYSERROR
(
"Failed to set FD_CLOEXEC on client socket connection %d
.
"
,
clientfd
);
SYSERROR
(
"Failed to set FD_CLOEXEC on client socket connection %d"
,
clientfd
);
goto
err1
;
goto
err1
;
}
}
if
(
getsockopt
(
clientfd
,
SOL_SOCKET
,
SO_PEERCRED
,
&
cred
,
&
credsz
))
if
(
getsockopt
(
clientfd
,
SOL_SOCKET
,
SO_PEERCRED
,
&
cred
,
&
credsz
))
{
{
SYSERROR
(
"Failed to get credentials on client socket connection %d"
,
clientfd
);
ERROR
(
"Failed to get credentials on client socket connection %d."
,
clientfd
);
goto
err1
;
goto
err1
;
}
}
if
(
cred
.
uid
&&
cred
.
uid
!=
geteuid
())
{
if
(
cred
.
uid
&&
cred
.
uid
!=
geteuid
())
{
WARN
(
"Monitor denied for uid %d on client socket connection %d."
,
cred
.
uid
,
clientfd
);
WARN
(
"Monitor denied for uid %d on client socket connection %d"
,
cred
.
uid
,
clientfd
);
ret
=
-
EACCES
;
goto
err1
;
goto
err1
;
}
}
if
(
mon
->
clientfds_cnt
+
1
>
mon
->
clientfds_size
)
{
if
(
mon
->
clientfds_cnt
+
1
>
mon
->
clientfds_size
)
{
int
*
clientfds
;
int
*
clientfds
;
clientfds
=
realloc
(
mon
->
clientfds
,
clientfds
=
realloc
(
mon
->
clientfds
,
(
mon
->
clientfds_size
+
CLIENTFDS_CHUNK
)
*
sizeof
(
mon
->
clientfds
[
0
]));
(
mon
->
clientfds_size
+
CLIENTFDS_CHUNK
)
*
sizeof
(
mon
->
clientfds
[
0
]));
if
(
clientfds
==
NULL
)
{
if
(
clientfds
==
NULL
)
{
ERROR
(
"Failed to realloc memory for %d client file "
ERROR
(
"Failed to realloc memory for %d client file descriptors"
,
"descriptors."
,
mon
->
clientfds_size
+
CLIENTFDS_CHUNK
);
mon
->
clientfds_size
+
CLIENTFDS_CHUNK
);
goto
err1
;
goto
err1
;
}
}
mon
->
clientfds
=
clientfds
;
mon
->
clientfds
=
clientfds
;
mon
->
clientfds_size
+=
CLIENTFDS_CHUNK
;
mon
->
clientfds_size
+=
CLIENTFDS_CHUNK
;
}
}
ret
=
lxc_mainloop_add_handler
(
&
mon
->
descr
,
clientfd
,
ret
=
lxc_mainloop_add_handler
(
&
mon
->
descr
,
clientfd
,
lxc_monitord_sock_handler
,
mon
);
lxc_monitord_sock_handler
,
mon
);
if
(
ret
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to add socket handler
.
"
);
ERROR
(
"Failed to add socket handler"
);
goto
err1
;
goto
err1
;
}
}
mon
->
clientfds
[
mon
->
clientfds_cnt
++
]
=
clientfd
;
mon
->
clientfds
[
mon
->
clientfds_cnt
++
]
=
clientfd
;
INFO
(
"Accepted client file descriptor %d. Number of accepted file descriptors is now %d."
,
clientfd
,
mon
->
clientfds_cnt
);
INFO
(
"Accepted client file descriptor %d. Number of accepted file descriptors is now %d"
,
clientfd
,
mon
->
clientfds_cnt
);
goto
out
;
goto
out
;
err1:
err1:
close
(
clientfd
);
close
(
clientfd
);
out:
out:
return
ret
;
return
ret
;
}
}
...
@@ -255,8 +260,10 @@ static int lxc_monitord_sock_delete(struct lxc_monitor *mon)
...
@@ -255,8 +260,10 @@ static int lxc_monitord_sock_delete(struct lxc_monitor *mon)
if
(
lxc_monitor_sock_name
(
mon
->
lxcpath
,
&
addr
)
<
0
)
if
(
lxc_monitor_sock_name
(
mon
->
lxcpath
,
&
addr
)
<
0
)
return
-
1
;
return
-
1
;
if
(
addr
.
sun_path
[
0
])
if
(
addr
.
sun_path
[
0
])
unlink
(
addr
.
sun_path
);
unlink
(
addr
.
sun_path
);
return
0
;
return
0
;
}
}
...
@@ -268,8 +275,7 @@ static int lxc_monitord_create(struct lxc_monitor *mon)
...
@@ -268,8 +275,7 @@ static int lxc_monitord_create(struct lxc_monitor *mon)
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
ret
=
lxc_monitord_sock_create
(
mon
);
return
lxc_monitord_sock_create
(
mon
);
return
ret
;
}
}
static
void
lxc_monitord_delete
(
struct
lxc_monitor
*
mon
)
static
void
lxc_monitord_delete
(
struct
lxc_monitor
*
mon
)
...
@@ -277,7 +283,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
...
@@ -277,7 +283,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
int
i
;
int
i
;
lxc_mainloop_del_handler
(
&
mon
->
descr
,
mon
->
listenfd
);
lxc_mainloop_del_handler
(
&
mon
->
descr
,
mon
->
listenfd
);
close
(
mon
->
listenfd
);
lxc_abstract_unix_
close
(
mon
->
listenfd
);
lxc_monitord_sock_delete
(
mon
);
lxc_monitord_sock_delete
(
mon
);
lxc_mainloop_del_handler
(
&
mon
->
descr
,
mon
->
fifofd
);
lxc_mainloop_del_handler
(
&
mon
->
descr
,
mon
->
fifofd
);
...
@@ -288,6 +294,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
...
@@ -288,6 +294,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
lxc_mainloop_del_handler
(
&
mon
->
descr
,
mon
->
clientfds
[
i
]);
lxc_mainloop_del_handler
(
&
mon
->
descr
,
mon
->
clientfds
[
i
]);
close
(
mon
->
clientfds
[
i
]);
close
(
mon
->
clientfds
[
i
]);
}
}
mon
->
clientfds_cnt
=
0
;
mon
->
clientfds_cnt
=
0
;
}
}
...
@@ -321,14 +328,14 @@ static int lxc_monitord_mainloop_add(struct lxc_monitor *mon)
...
@@ -321,14 +328,14 @@ static int lxc_monitord_mainloop_add(struct lxc_monitor *mon)
ret
=
lxc_mainloop_add_handler
(
&
mon
->
descr
,
mon
->
fifofd
,
ret
=
lxc_mainloop_add_handler
(
&
mon
->
descr
,
mon
->
fifofd
,
lxc_monitord_fifo_handler
,
mon
);
lxc_monitord_fifo_handler
,
mon
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to add to mainloop monitor handler for fifo
.
"
);
ERROR
(
"Failed to add to mainloop monitor handler for fifo"
);
return
-
1
;
return
-
1
;
}
}
ret
=
lxc_mainloop_add_handler
(
&
mon
->
descr
,
mon
->
listenfd
,
ret
=
lxc_mainloop_add_handler
(
&
mon
->
descr
,
mon
->
listenfd
,
lxc_monitord_sock_accept
,
mon
);
lxc_monitord_sock_accept
,
mon
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to add to mainloop monitor handler for listen socket
.
"
);
ERROR
(
"Failed to add to mainloop monitor handler for listen socket"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -374,9 +381,10 @@ int main(int argc, char *argv[])
...
@@ -374,9 +381,10 @@ int main(int argc, char *argv[])
log
.
prefix
=
"lxc-monitord"
;
log
.
prefix
=
"lxc-monitord"
;
log
.
quiet
=
0
;
log
.
quiet
=
0
;
log
.
lxcpath
=
lxcpath
;
log
.
lxcpath
=
lxcpath
;
ret
=
lxc_log_init
(
&
log
);
ret
=
lxc_log_init
(
&
log
);
if
(
ret
)
if
(
ret
)
INFO
(
"Failed to open log file %s, log will be lost
.
"
,
lxcpath
);
INFO
(
"Failed to open log file %s, log will be lost"
,
lxcpath
);
lxc_log_options_no_override
();
lxc_log_options_no_override
();
if
(
lxc_safe_int
(
argv
[
2
],
&
pipefd
)
<
0
)
if
(
lxc_safe_int
(
argv
[
2
],
&
pipefd
)
<
0
)
...
@@ -388,7 +396,7 @@ int main(int argc, char *argv[])
...
@@ -388,7 +396,7 @@ int main(int argc, char *argv[])
sigdelset
(
&
mask
,
SIGBUS
)
||
sigdelset
(
&
mask
,
SIGBUS
)
||
sigdelset
(
&
mask
,
SIGTERM
)
||
sigdelset
(
&
mask
,
SIGTERM
)
||
pthread_sigmask
(
SIG_BLOCK
,
&
mask
,
NULL
))
{
pthread_sigmask
(
SIG_BLOCK
,
&
mask
,
NULL
))
{
SYSERROR
(
"Failed to set signal mask
.
"
);
SYSERROR
(
"Failed to set signal mask"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
...
@@ -401,10 +409,11 @@ int main(int argc, char *argv[])
...
@@ -401,10 +409,11 @@ int main(int argc, char *argv[])
goto
on_signal
;
goto
on_signal
;
ret
=
EXIT_FAILURE
;
ret
=
EXIT_FAILURE
;
memset
(
&
mon
,
0
,
sizeof
(
mon
));
memset
(
&
mon
,
0
,
sizeof
(
mon
));
mon
.
lxcpath
=
lxcpath
;
mon
.
lxcpath
=
lxcpath
;
if
(
lxc_mainloop_open
(
&
mon
.
descr
))
{
if
(
lxc_mainloop_open
(
&
mon
.
descr
))
{
ERROR
(
"Failed to create mainloop
.
"
);
ERROR
(
"Failed to create mainloop"
);
goto
on_error
;
goto
on_error
;
}
}
mainloop_opened
=
true
;
mainloop_opened
=
true
;
...
@@ -424,33 +433,38 @@ int main(int argc, char *argv[])
...
@@ -424,33 +433,38 @@ int main(int argc, char *argv[])
close
(
pipefd
);
close
(
pipefd
);
if
(
lxc_monitord_mainloop_add
(
&
mon
))
{
if
(
lxc_monitord_mainloop_add
(
&
mon
))
{
ERROR
(
"Failed to add mainloop handlers
.
"
);
ERROR
(
"Failed to add mainloop handlers"
);
goto
on_error
;
goto
on_error
;
}
}
NOTICE
(
"lxc-monitord with pid %d is now monitoring lxcpath %s
.
"
,
NOTICE
(
"lxc-monitord with pid %d is now monitoring lxcpath %s"
,
lxc_raw_getpid
(),
mon
.
lxcpath
);
lxc_raw_getpid
(),
mon
.
lxcpath
);
for
(;;)
{
for
(;;)
{
ret
=
lxc_mainloop
(
&
mon
.
descr
,
1000
*
30
);
ret
=
lxc_mainloop
(
&
mon
.
descr
,
1000
*
30
);
if
(
ret
)
{
if
(
ret
)
{
ERROR
(
"mainloop returned an error"
);
ERROR
(
"mainloop returned an error"
);
break
;
break
;
}
}
if
(
mon
.
clientfds_cnt
<=
0
)
{
if
(
mon
.
clientfds_cnt
<=
0
)
{
NOTICE
(
"No remaining clients. lxc-monitord is exiting
.
"
);
NOTICE
(
"No remaining clients. lxc-monitord is exiting"
);
break
;
break
;
}
}
if
(
quit
==
1
)
{
NOTICE
(
"got quit command. lxc-monitord is exitting."
);
if
(
quit
==
LXC_MAINLOOP_CLOSE
)
{
NOTICE
(
"Got quit command. lxc-monitord is exitting"
);
break
;
break
;
}
}
}
}
on_signal:
on_signal:
ret
=
EXIT_SUCCESS
;
ret
=
EXIT_SUCCESS
;
on_error:
on_error:
if
(
monitord_created
)
if
(
monitord_created
)
lxc_monitord_cleanup
();
lxc_monitord_cleanup
();
if
(
mainloop_opened
)
if
(
mainloop_opened
)
lxc_mainloop_close
(
&
mon
.
descr
);
lxc_mainloop_close
(
&
mon
.
descr
);
...
...
src/lxc/commands.c
View file @
010a85d1
...
@@ -240,18 +240,21 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
...
@@ -240,18 +240,21 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
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
)
{
if
(
errno
==
EPIPE
)
{
close
(
client_fd
);
close
(
client_fd
);
if
(
errno
==
EPIPE
)
return
-
EPIPE
;
return
-
EPIPE
;
}
if
(
ret
>=
0
)
close
(
client_fd
);
return
-
EMSGSIZE
;
return
-
1
;
return
-
1
;
}
}
if
((
size_t
)
ret
!=
sizeof
(
cmd
->
req
))
{
close
(
client_fd
);
return
-
EMSGSIZE
;
}
if
(
cmd
->
req
.
datalen
<=
0
)
if
(
cmd
->
req
.
datalen
<=
0
)
return
client_fd
;
return
client_fd
;
...
@@ -754,7 +757,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
...
@@ -754,7 +757,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
rsp
.
data
=
INT_TO_PTR
(
ttynum
);
rsp
.
data
=
INT_TO_PTR
(
ttynum
);
ret
=
lxc_abstract_unix_send_fds
(
fd
,
&
masterfd
,
1
,
&
rsp
,
sizeof
(
rsp
));
ret
=
lxc_abstract_unix_send_fds
(
fd
,
&
masterfd
,
1
,
&
rsp
,
sizeof
(
rsp
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to send tty to client"
);
SYS
ERROR
(
"Failed to send tty to client"
);
lxc_terminal_free
(
handler
->
conf
,
fd
);
lxc_terminal_free
(
handler
->
conf
,
fd
);
goto
out_close
;
goto
out_close
;
}
}
...
@@ -1112,17 +1115,17 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
...
@@ -1112,17 +1115,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
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to receive data on command socket for command "
"
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
if
(
errno
==
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
;
}
}
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to receive data on command socket for command "
"
\"
%s
\"
"
,
lxc_cmd_str
(
req
.
cmd
));
goto
out_close
;
goto
out_close
;
}
}
...
...
src/lxc/confile_utils.c
View file @
010a85d1
...
@@ -149,6 +149,7 @@ int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
...
@@ -149,6 +149,7 @@ int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
*/
*/
if
(
*
(
slide
+
strspn
(
slide
,
"
\t\r\n
"
))
!=
'\0'
)
if
(
*
(
slide
+
strspn
(
slide
,
"
\t\r\n
"
))
!=
'\0'
)
goto
on_error
;
goto
on_error
;
/* Mark end of range. */
/* Mark end of range. */
*
slide
=
'\0'
;
*
slide
=
'\0'
;
...
@@ -211,6 +212,7 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail
...
@@ -211,6 +212,7 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail
lxc_list_add_tail
(
networks
,
newlist
);
lxc_list_add_tail
(
networks
,
newlist
);
else
else
lxc_list_add
(
networks
,
newlist
);
lxc_list_add
(
networks
,
newlist
);
return
netdev
;
return
netdev
;
}
}
...
@@ -265,23 +267,29 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
...
@@ -265,23 +267,29 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE
(
"index: %zd"
,
netdev
->
idx
);
TRACE
(
"index: %zd"
,
netdev
->
idx
);
TRACE
(
"ifindex: %d"
,
netdev
->
ifindex
);
TRACE
(
"ifindex: %d"
,
netdev
->
ifindex
);
switch
(
netdev
->
type
)
{
switch
(
netdev
->
type
)
{
case
LXC_NET_VETH
:
case
LXC_NET_VETH
:
TRACE
(
"type: veth"
);
TRACE
(
"type: veth"
);
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
TRACE
(
"veth pair: %s"
,
TRACE
(
"veth pair: %s"
,
netdev
->
priv
.
veth_attr
.
pair
);
netdev
->
priv
.
veth_attr
.
pair
);
if
(
netdev
->
priv
.
veth_attr
.
veth1
[
0
]
!=
'\0'
)
if
(
netdev
->
priv
.
veth_attr
.
veth1
[
0
]
!=
'\0'
)
TRACE
(
"veth1 : %s"
,
TRACE
(
"veth1 : %s"
,
netdev
->
priv
.
veth_attr
.
veth1
);
netdev
->
priv
.
veth_attr
.
veth1
);
if
(
netdev
->
priv
.
veth_attr
.
ifindex
>
0
)
if
(
netdev
->
priv
.
veth_attr
.
ifindex
>
0
)
TRACE
(
"host side ifindex for veth device: %d"
,
TRACE
(
"host side ifindex for veth device: %d"
,
netdev
->
priv
.
veth_attr
.
ifindex
);
netdev
->
priv
.
veth_attr
.
ifindex
);
break
;
break
;
case
LXC_NET_MACVLAN
:
case
LXC_NET_MACVLAN
:
TRACE
(
"type: macvlan"
);
TRACE
(
"type: macvlan"
);
if
(
netdev
->
priv
.
macvlan_attr
.
mode
>
0
)
{
if
(
netdev
->
priv
.
macvlan_attr
.
mode
>
0
)
{
char
*
macvlan_mode
;
char
*
macvlan_mode
;
macvlan_mode
=
lxc_macvlan_flag_to_mode
(
macvlan_mode
=
lxc_macvlan_flag_to_mode
(
netdev
->
priv
.
macvlan_attr
.
mode
);
netdev
->
priv
.
macvlan_attr
.
mode
);
TRACE
(
"macvlan mode: %s"
,
TRACE
(
"macvlan mode: %s"
,
...
@@ -295,10 +303,10 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
...
@@ -295,10 +303,10 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
break
;
break
;
case
LXC_NET_PHYS
:
case
LXC_NET_PHYS
:
TRACE
(
"type: phys"
);
TRACE
(
"type: phys"
);
if
(
netdev
->
priv
.
phys_attr
.
ifindex
>
0
)
{
if
(
netdev
->
priv
.
phys_attr
.
ifindex
>
0
)
TRACE
(
"host side ifindex for phys device: %d"
,
TRACE
(
"host side ifindex for phys device: %d"
,
netdev
->
priv
.
phys_attr
.
ifindex
);
netdev
->
priv
.
phys_attr
.
ifindex
);
}
break
;
break
;
case
LXC_NET_EMPTY
:
case
LXC_NET_EMPTY
:
TRACE
(
"type: empty"
);
TRACE
(
"type: empty"
);
...
@@ -314,16 +322,22 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
...
@@ -314,16 +322,22 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
if
(
netdev
->
type
!=
LXC_NET_EMPTY
)
{
if
(
netdev
->
type
!=
LXC_NET_EMPTY
)
{
TRACE
(
"flags: %s"
,
TRACE
(
"flags: %s"
,
netdev
->
flags
==
IFF_UP
?
"up"
:
"none"
);
netdev
->
flags
==
IFF_UP
?
"up"
:
"none"
);
if
(
netdev
->
link
[
0
]
!=
'\0'
)
if
(
netdev
->
link
[
0
]
!=
'\0'
)
TRACE
(
"link: %s"
,
netdev
->
link
);
TRACE
(
"link: %s"
,
netdev
->
link
);
if
(
netdev
->
name
[
0
]
!=
'\0'
)
if
(
netdev
->
name
[
0
]
!=
'\0'
)
TRACE
(
"name: %s"
,
netdev
->
name
);
TRACE
(
"name: %s"
,
netdev
->
name
);
if
(
netdev
->
hwaddr
)
if
(
netdev
->
hwaddr
)
TRACE
(
"hwaddr: %s"
,
netdev
->
hwaddr
);
TRACE
(
"hwaddr: %s"
,
netdev
->
hwaddr
);
if
(
netdev
->
mtu
)
if
(
netdev
->
mtu
)
TRACE
(
"mtu: %s"
,
netdev
->
mtu
);
TRACE
(
"mtu: %s"
,
netdev
->
mtu
);
if
(
netdev
->
upscript
)
if
(
netdev
->
upscript
)
TRACE
(
"upscript: %s"
,
netdev
->
upscript
);
TRACE
(
"upscript: %s"
,
netdev
->
upscript
);
if
(
netdev
->
downscript
)
if
(
netdev
->
downscript
)
TRACE
(
"downscript: %s"
,
netdev
->
downscript
);
TRACE
(
"downscript: %s"
,
netdev
->
downscript
);
...
@@ -345,11 +359,13 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
...
@@ -345,11 +359,13 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE
(
"ipv6 gateway auto: %s"
,
TRACE
(
"ipv6 gateway auto: %s"
,
netdev
->
ipv6_gateway_auto
?
"true"
:
"false"
);
netdev
->
ipv6_gateway_auto
?
"true"
:
"false"
);
if
(
netdev
->
ipv6_gateway
)
{
if
(
netdev
->
ipv6_gateway
)
{
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
));
bufinet6
,
sizeof
(
bufinet6
));
TRACE
(
"ipv6 gateway: %s"
,
bufinet6
);
TRACE
(
"ipv6 gateway: %s"
,
bufinet6
);
}
}
lxc_list_for_each_safe
(
cur
,
&
netdev
->
ipv6
,
next
)
{
lxc_list_for_each_safe
(
cur
,
&
netdev
->
ipv6
,
next
)
{
inet6dev
=
cur
->
elem
;
inet6dev
=
cur
->
elem
;
inet_ntop
(
AF_INET6
,
&
inet6dev
->
addr
,
bufinet6
,
inet_ntop
(
AF_INET6
,
&
inet6dev
->
addr
,
bufinet6
,
...
@@ -477,7 +493,7 @@ int set_config_string_item(char **conf_item, const char *value)
...
@@ -477,7 +493,7 @@ int set_config_string_item(char **conf_item, const char *value)
new_value
=
strdup
(
value
);
new_value
=
strdup
(
value
);
if
(
!
new_value
)
{
if
(
!
new_value
)
{
SYSERROR
(
"
f
ailed to duplicate string
\"
%s
\"
"
,
value
);
SYSERROR
(
"
F
ailed to duplicate string
\"
%s
\"
"
,
value
);
return
-
1
;
return
-
1
;
}
}
...
@@ -505,8 +521,10 @@ int config_ip_prefix(struct in_addr *addr)
...
@@ -505,8 +521,10 @@ int config_ip_prefix(struct in_addr *addr)
{
{
if
(
IN_CLASSA
(
addr
->
s_addr
))
if
(
IN_CLASSA
(
addr
->
s_addr
))
return
32
-
IN_CLASSA_NSHIFT
;
return
32
-
IN_CLASSA_NSHIFT
;
if
(
IN_CLASSB
(
addr
->
s_addr
))
if
(
IN_CLASSB
(
addr
->
s_addr
))
return
32
-
IN_CLASSB_NSHIFT
;
return
32
-
IN_CLASSB_NSHIFT
;
if
(
IN_CLASSC
(
addr
->
s_addr
))
if
(
IN_CLASSC
(
addr
->
s_addr
))
return
32
-
IN_CLASSC_NSHIFT
;
return
32
-
IN_CLASSC_NSHIFT
;
...
@@ -521,15 +539,14 @@ int network_ifname(char *valuep, const char *value, size_t size)
...
@@ -521,15 +539,14 @@ int network_ifname(char *valuep, const char *value, size_t size)
return
-
1
;
return
-
1
;
retlen
=
strlcpy
(
valuep
,
value
,
size
);
retlen
=
strlcpy
(
valuep
,
value
,
size
);
if
(
retlen
>=
size
)
{
if
(
retlen
>=
size
)
ERROR
(
"Network devie name
\"
%s
\"
is too long (>= %zu)"
,
value
,
ERROR
(
"Network devie name
\"
%s
\"
is too long (>= %zu)"
,
value
,
size
);
size
);
}
return
0
;
return
0
;
}
}
int
rand_complete_hwaddr
(
char
*
hwaddr
)
void
rand_complete_hwaddr
(
char
*
hwaddr
)
{
{
const
char
hex
[]
=
"0123456789abcdef"
;
const
char
hex
[]
=
"0123456789abcdef"
;
char
*
curs
=
hwaddr
;
char
*
curs
=
hwaddr
;
...
@@ -558,7 +575,6 @@ int rand_complete_hwaddr(char *hwaddr)
...
@@ -558,7 +575,6 @@ int rand_complete_hwaddr(char *hwaddr)
}
}
curs
++
;
curs
++
;
}
}
return
0
;
}
}
bool
lxc_config_net_hwaddr
(
const
char
*
line
)
bool
lxc_config_net_hwaddr
(
const
char
*
line
)
...
@@ -568,11 +584,15 @@ bool lxc_config_net_hwaddr(const char *line)
...
@@ -568,11 +584,15 @@ bool lxc_config_net_hwaddr(const char *line)
if
(
strncmp
(
line
,
"lxc.net"
,
7
)
!=
0
)
if
(
strncmp
(
line
,
"lxc.net"
,
7
)
!=
0
)
return
false
;
return
false
;
if
(
strncmp
(
line
,
"lxc.net.hwaddr"
,
14
)
==
0
)
if
(
strncmp
(
line
,
"lxc.net.hwaddr"
,
14
)
==
0
)
return
true
;
return
true
;
if
(
strncmp
(
line
,
"lxc.network.hwaddr"
,
18
)
==
0
)
if
(
strncmp
(
line
,
"lxc.network.hwaddr"
,
18
)
==
0
)
return
true
;
return
true
;
if
(
sscanf
(
line
,
"lxc.net.%u.%6s"
,
&
index
,
tmp
)
==
2
||
sscanf
(
line
,
"lxc.network.%u.%6s"
,
&
index
,
tmp
)
==
2
)
if
(
sscanf
(
line
,
"lxc.net.%u.%6s"
,
&
index
,
tmp
)
==
2
||
sscanf
(
line
,
"lxc.network.%u.%6s"
,
&
index
,
tmp
)
==
2
)
return
strncmp
(
tmp
,
"hwaddr"
,
6
)
==
0
;
return
strncmp
(
tmp
,
"hwaddr"
,
6
)
==
0
;
return
false
;
return
false
;
...
@@ -639,7 +659,7 @@ int lxc_get_conf_str(char *retv, int inlen, const char *value)
...
@@ -639,7 +659,7 @@ int lxc_get_conf_str(char *retv, int inlen, const char *value)
if
(
retv
&&
inlen
>=
value_len
+
1
)
if
(
retv
&&
inlen
>=
value_len
+
1
)
memcpy
(
retv
,
value
,
value_len
+
1
);
memcpy
(
retv
,
value
,
value_len
+
1
);
return
strlen
(
value
)
;
return
value_len
;
}
}
int
lxc_get_conf_int
(
struct
lxc_conf
*
c
,
char
*
retv
,
int
inlen
,
int
v
)
int
lxc_get_conf_int
(
struct
lxc_conf
*
c
,
char
*
retv
,
int
inlen
,
int
v
)
...
@@ -701,6 +721,7 @@ bool parse_limit_value(const char **value, rlim_t *res)
...
@@ -701,6 +721,7 @@ bool parse_limit_value(const char **value, rlim_t *res)
*
res
=
strtoull
(
*
value
,
&
endptr
,
10
);
*
res
=
strtoull
(
*
value
,
&
endptr
,
10
);
if
(
errno
||
!
endptr
)
if
(
errno
||
!
endptr
)
return
false
;
return
false
;
*
value
=
endptr
;
*
value
=
endptr
;
return
true
;
return
true
;
...
@@ -744,7 +765,7 @@ static int lxc_container_name_to_pid(const char *lxcname_or_pid,
...
@@ -744,7 +765,7 @@ static int lxc_container_name_to_pid(const char *lxcname_or_pid,
ret
=
kill
(
pid
,
0
);
ret
=
kill
(
pid
,
0
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to send signal to pid %d"
,
(
int
)
pid
);
SYSERROR
(
"Failed to send signal to pid %d"
,
(
int
)
pid
);
return
-
EPERM
;
return
-
1
;
}
}
return
pid
;
return
pid
;
...
@@ -760,7 +781,7 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
...
@@ -760,7 +781,7 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
if
(
lastslash
)
{
if
(
lastslash
)
{
dup
=
strdup
(
lxcname_or_pid
);
dup
=
strdup
(
lxcname_or_pid
);
if
(
!
dup
)
if
(
!
dup
)
return
-
ENOMEM
;
return
-
1
;
dup
[
lastslash
-
lxcname_or_pid
]
=
'\0'
;
dup
[
lastslash
-
lxcname_or_pid
]
=
'\0'
;
pid
=
lxc_container_name_to_pid
(
lastslash
+
1
,
dup
);
pid
=
lxc_container_name_to_pid
(
lastslash
+
1
,
dup
);
...
@@ -770,11 +791,11 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
...
@@ -770,11 +791,11 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
}
}
if
(
pid
<
0
)
if
(
pid
<
0
)
return
-
EINVAL
;
return
-
1
;
fd
=
lxc_preserve_ns
(
pid
,
namespace
);
fd
=
lxc_preserve_ns
(
pid
,
namespace
);
if
(
fd
<
0
)
if
(
fd
<
0
)
return
-
EINVAL
;
return
-
1
;
return
fd
;
return
fd
;
}
}
...
@@ -877,9 +898,8 @@ static int rt_sig_num(const char *signame)
...
@@ -877,9 +898,8 @@ static int rt_sig_num(const char *signame)
{
{
int
rtmax
=
0
,
sig_n
=
0
;
int
rtmax
=
0
,
sig_n
=
0
;
if
(
strncasecmp
(
signame
,
"max-"
,
4
)
==
0
)
{
if
(
strncasecmp
(
signame
,
"max-"
,
4
)
==
0
)
rtmax
=
1
;
rtmax
=
1
;
}
signame
+=
4
;
signame
+=
4
;
if
(
!
isdigit
(
*
signame
))
if
(
!
isdigit
(
*
signame
))
...
@@ -903,11 +923,11 @@ int sig_parse(const char *signame)
...
@@ -903,11 +923,11 @@ int sig_parse(const char *signame)
signame
+=
3
;
signame
+=
3
;
if
(
strncasecmp
(
signame
,
"rt"
,
2
)
==
0
)
if
(
strncasecmp
(
signame
,
"rt"
,
2
)
==
0
)
return
rt_sig_num
(
signame
+
2
);
return
rt_sig_num
(
signame
+
2
);
for
(
n
=
0
;
n
<
sizeof
(
signames
)
/
sizeof
((
signames
)[
0
]);
n
++
)
{
for
(
n
=
0
;
n
<
sizeof
(
signames
)
/
sizeof
((
signames
)[
0
]);
n
++
)
if
(
strcasecmp
(
signames
[
n
].
name
,
signame
)
==
0
)
if
(
strcasecmp
(
signames
[
n
].
name
,
signame
)
==
0
)
return
signames
[
n
].
num
;
return
signames
[
n
].
num
;
}
}
}
return
-
1
;
return
-
1
;
}
}
src/lxc/confile_utils.h
View file @
010a85d1
...
@@ -81,7 +81,7 @@ extern int set_config_string_item_max(char **conf_item, const char *value,
...
@@ -81,7 +81,7 @@ extern int set_config_string_item_max(char **conf_item, const char *value,
extern
int
set_config_path_item
(
char
**
conf_item
,
const
char
*
value
);
extern
int
set_config_path_item
(
char
**
conf_item
,
const
char
*
value
);
extern
int
config_ip_prefix
(
struct
in_addr
*
addr
);
extern
int
config_ip_prefix
(
struct
in_addr
*
addr
);
extern
int
network_ifname
(
char
*
valuep
,
const
char
*
value
,
size_t
size
);
extern
int
network_ifname
(
char
*
valuep
,
const
char
*
value
,
size_t
size
);
extern
int
rand_complete_hwaddr
(
char
*
hwaddr
);
extern
void
rand_complete_hwaddr
(
char
*
hwaddr
);
extern
bool
lxc_config_net_hwaddr
(
const
char
*
line
);
extern
bool
lxc_config_net_hwaddr
(
const
char
*
line
);
extern
void
update_hwaddr
(
const
char
*
line
);
extern
void
update_hwaddr
(
const
char
*
line
);
extern
bool
new_hwaddr
(
char
*
hwaddr
);
extern
bool
new_hwaddr
(
char
*
hwaddr
);
...
...
src/lxc/lxccontainer.c
View file @
010a85d1
...
@@ -167,11 +167,12 @@ static int ongoing_create(struct lxc_container *c)
...
@@ -167,11 +167,12 @@ static int ongoing_create(struct lxc_container *c)
ret
=
fcntl
(
fd
,
F_OFD_GETLK
,
&
lk
);
ret
=
fcntl
(
fd
,
F_OFD_GETLK
,
&
lk
);
if
(
ret
<
0
&&
errno
==
EINVAL
)
if
(
ret
<
0
&&
errno
==
EINVAL
)
ret
=
flock
(
fd
,
LOCK_EX
|
LOCK_NB
);
ret
=
flock
(
fd
,
LOCK_EX
|
LOCK_NB
);
close
(
fd
);
close
(
fd
);
if
(
ret
==
0
&&
lk
.
l_pid
!=
-
1
)
{
if
(
ret
==
0
&&
lk
.
l_pid
!=
-
1
)
/* create is still ongoing */
/* create is still ongoing */
return
1
;
return
1
;
}
/* Create completed but partial is still there. */
/* Create completed but partial is still there. */
return
2
;
return
2
;
...
@@ -221,6 +222,7 @@ static void remove_partial(struct lxc_container *c, int fd)
...
@@ -221,6 +222,7 @@ static void remove_partial(struct lxc_container *c, int fd)
char
*
path
;
char
*
path
;
close
(
fd
);
close
(
fd
);
/* $lxcpath + '/' + $name + '/partial' + \0 */
/* $lxcpath + '/' + $name + '/partial' + \0 */
len
=
strlen
(
c
->
config_path
)
+
strlen
(
c
->
name
)
+
10
;
len
=
strlen
(
c
->
config_path
)
+
strlen
(
c
->
name
)
+
10
;
path
=
alloca
(
len
);
path
=
alloca
(
len
);
...
@@ -254,7 +256,6 @@ static void remove_partial(struct lxc_container *c, int fd)
...
@@ -254,7 +256,6 @@ static void remove_partial(struct lxc_container *c, int fd)
* decrement numthreads under privlock, then if it hits 0 you can delete.
* decrement numthreads under privlock, then if it hits 0 you can delete.
* Do not ever use a lxccontainer whose numthreads you did not bump.
* Do not ever use a lxccontainer whose numthreads you did not bump.
*/
*/
static
void
lxc_container_free
(
struct
lxc_container
*
c
)
static
void
lxc_container_free
(
struct
lxc_container
*
c
)
{
{
if
(
!
c
)
if
(
!
c
)
...
@@ -358,7 +359,6 @@ int lxc_container_put(struct lxc_container *c)
...
@@ -358,7 +359,6 @@ int lxc_container_put(struct lxc_container *c)
}
}
container_mem_unlock
(
c
);
container_mem_unlock
(
c
);
return
0
;
return
0
;
}
}
...
@@ -385,7 +385,6 @@ static bool do_lxcapi_is_defined(struct lxc_container *c)
...
@@ -385,7 +385,6 @@ static bool do_lxcapi_is_defined(struct lxc_container *c)
on_error:
on_error:
container_mem_unlock
(
c
);
container_mem_unlock
(
c
);
return
ret
;
return
ret
;
}
}
...
@@ -596,7 +595,6 @@ static bool load_config_locked(struct lxc_container *c, const char *fname)
...
@@ -596,7 +595,6 @@ static bool load_config_locked(struct lxc_container *c, const char *fname)
return
false
;
return
false
;
c
->
lxc_conf
->
name
=
c
->
name
;
c
->
lxc_conf
->
name
=
c
->
name
;
return
true
;
return
true
;
}
}
...
@@ -610,8 +608,10 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
...
@@ -610,8 +608,10 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
return
false
;
return
false
;
fname
=
c
->
configfile
;
fname
=
c
->
configfile
;
if
(
alt_file
)
if
(
alt_file
)
fname
=
alt_file
;
fname
=
alt_file
;
if
(
!
fname
)
if
(
!
fname
)
return
false
;
return
false
;
...
@@ -746,9 +746,8 @@ static char **split_init_cmd(const char *incmd)
...
@@ -746,9 +746,8 @@ static char **split_init_cmd(const char *incmd)
len
=
strlen
(
incmd
)
+
1
;
len
=
strlen
(
incmd
)
+
1
;
copy
=
alloca
(
len
);
copy
=
alloca
(
len
);
retlen
=
strlcpy
(
copy
,
incmd
,
len
);
retlen
=
strlcpy
(
copy
,
incmd
,
len
);
if
(
retlen
>=
len
)
{
if
(
retlen
>=
len
)
return
NULL
;
return
NULL
;
}
do
{
do
{
argv
=
malloc
(
sizeof
(
char
*
));
argv
=
malloc
(
sizeof
(
char
*
));
...
@@ -786,11 +785,11 @@ static int lxc_rcv_status(int state_socket)
...
@@ -786,11 +785,11 @@ static int lxc_rcv_status(int state_socket)
again
:
again
:
/* Receive container state. */
/* Receive container state. */
ret
=
lxc_abstract_unix_rcv_credential
(
state_socket
,
&
state
,
ret
=
lxc_abstract_unix_rcv_credential
(
state_socket
,
&
state
,
sizeof
(
int
));
sizeof
(
int
));
if
(
ret
<=
0
)
{
if
(
ret
<=
0
)
{
if
(
errno
!=
EINTR
)
if
(
errno
!=
EINTR
)
return
-
1
;
return
-
1
;
TRACE
(
"Caught EINTR; retrying"
);
TRACE
(
"Caught EINTR; retrying"
);
goto
again
;
goto
again
;
}
}
...
@@ -1147,6 +1146,7 @@ static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
...
@@ -1147,6 +1146,7 @@ static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
on_error
:
on_error
:
if
(
inargs
)
{
if
(
inargs
)
{
char
**
arg
;
char
**
arg
;
for
(
arg
=
inargs
;
*
arg
;
arg
++
)
for
(
arg
=
inargs
;
*
arg
;
arg
++
)
free
(
*
arg
);
free
(
*
arg
);
free
(
inargs
);
free
(
inargs
);
...
@@ -1405,9 +1405,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1405,9 +1405,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
* args.
* args.
*/
*/
if
(
argv
)
if
(
argv
)
for
(
nargs
=
0
;
argv
[
nargs
];
nargs
++
)
{
for
(
nargs
=
0
;
argv
[
nargs
];
nargs
++
)
;
;
}
/* template, path, rootfs and name args */
/* template, path, rootfs and name args */
nargs
+=
4
;
nargs
+=
4
;
...
@@ -1421,6 +1421,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1421,6 +1421,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
patharg
=
malloc
(
len
);
patharg
=
malloc
(
len
);
if
(
!
patharg
)
if
(
!
patharg
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
ret
=
snprintf
(
patharg
,
len
,
"--path=%s/%s"
,
c
->
config_path
,
c
->
name
);
ret
=
snprintf
(
patharg
,
len
,
"--path=%s/%s"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
len
)
if
(
ret
<
0
||
ret
>=
len
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
...
@@ -1431,6 +1432,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1431,6 +1432,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
namearg
=
malloc
(
len
);
namearg
=
malloc
(
len
);
if
(
!
namearg
)
if
(
!
namearg
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
ret
=
snprintf
(
namearg
,
len
,
"--name=%s"
,
c
->
name
);
ret
=
snprintf
(
namearg
,
len
,
"--name=%s"
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
len
)
if
(
ret
<
0
||
ret
>=
len
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
...
@@ -1441,6 +1443,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1441,6 +1443,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
rootfsarg
=
malloc
(
len
);
rootfsarg
=
malloc
(
len
);
if
(
!
rootfsarg
)
if
(
!
rootfsarg
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
ret
=
snprintf
(
rootfsarg
,
len
,
"--rootfs=%s"
,
bdev
->
dest
);
ret
=
snprintf
(
rootfsarg
,
len
,
"--rootfs=%s"
,
bdev
->
dest
);
if
(
ret
<
0
||
ret
>=
len
)
if
(
ret
<
0
||
ret
>=
len
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
...
@@ -1478,6 +1481,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1478,6 +1481,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
newargv
[
0
]
=
tpath
;
newargv
[
0
]
=
tpath
;
tpath
=
"lxc-usernsexec"
;
tpath
=
"lxc-usernsexec"
;
n2
[
0
]
=
"lxc-usernsexec"
;
n2
[
0
]
=
"lxc-usernsexec"
;
lxc_list_for_each
(
it
,
&
conf
->
id_map
)
{
lxc_list_for_each
(
it
,
&
conf
->
id_map
)
{
map
=
it
->
elem
;
map
=
it
->
elem
;
n2args
+=
2
;
n2args
+=
2
;
...
@@ -1499,6 +1503,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1499,6 +1503,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostuid_mapped
=
mapped_hostid
(
geteuid
(),
conf
,
ID_TYPE_UID
);
hostuid_mapped
=
mapped_hostid
(
geteuid
(),
conf
,
ID_TYPE_UID
);
extraargs
=
hostuid_mapped
>=
0
?
1
:
3
;
extraargs
=
hostuid_mapped
>=
0
?
1
:
3
;
n2
=
realloc
(
n2
,
(
nargs
+
n2args
+
extraargs
)
*
sizeof
(
char
*
));
n2
=
realloc
(
n2
,
(
nargs
+
n2args
+
extraargs
)
*
sizeof
(
char
*
));
if
(
!
n2
)
if
(
!
n2
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
...
@@ -1516,6 +1521,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1516,6 +1521,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
SYSERROR
(
"out of memory"
);
SYSERROR
(
"out of memory"
);
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
ret
=
snprintf
(
n2
[
n2args
-
1
],
200
,
"u:%d:%d:1"
,
ret
=
snprintf
(
n2
[
n2args
-
1
],
200
,
"u:%d:%d:1"
,
hostuid_mapped
,
geteuid
());
hostuid_mapped
,
geteuid
());
if
(
ret
<
0
||
ret
>=
200
)
if
(
ret
<
0
||
ret
>=
200
)
...
@@ -1524,6 +1530,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1524,6 +1530,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostgid_mapped
=
mapped_hostid
(
getegid
(),
conf
,
ID_TYPE_GID
);
hostgid_mapped
=
mapped_hostid
(
getegid
(),
conf
,
ID_TYPE_GID
);
extraargs
=
hostgid_mapped
>=
0
?
1
:
3
;
extraargs
=
hostgid_mapped
>=
0
?
1
:
3
;
n2
=
realloc
(
n2
,
(
nargs
+
n2args
+
extraargs
)
*
sizeof
(
char
*
));
n2
=
realloc
(
n2
,
(
nargs
+
n2args
+
extraargs
)
*
sizeof
(
char
*
));
if
(
!
n2
)
if
(
!
n2
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
...
@@ -1547,7 +1554,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
...
@@ -1547,7 +1554,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
if
(
ret
<
0
||
ret
>=
200
)
if
(
ret
<
0
||
ret
>=
200
)
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
n2
[
n2args
++
]
=
"--"
;
n2
[
n2args
++
]
=
"--"
;
for
(
i
=
0
;
i
<
nargs
;
i
++
)
for
(
i
=
0
;
i
<
nargs
;
i
++
)
n2
[
i
+
n2args
]
=
newargv
[
i
];
n2
[
i
+
n2args
]
=
newargv
[
i
];
n2args
+=
nargs
;
n2args
+=
nargs
;
...
@@ -1644,6 +1653,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
...
@@ -1644,6 +1653,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
goto
out_free_contents
;
goto
out_free_contents
;
contents
[
flen
]
=
'\0'
;
contents
[
flen
]
=
'\0'
;
ret
=
fclose
(
f
);
ret
=
fclose
(
f
);
f
=
NULL
;
f
=
NULL
;
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -1681,6 +1691,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
...
@@ -1681,6 +1691,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
}
}
fprintf
(
f
,
"
\n
"
);
fprintf
(
f
,
"
\n
"
);
}
}
#if HAVE_LIBGNUTLS
#if HAVE_LIBGNUTLS
fprintf
(
f
,
"# Template script checksum (SHA-1): "
);
fprintf
(
f
,
"# Template script checksum (SHA-1): "
);
for
(
i
=
0
;
i
<
SHA_DIGEST_LENGTH
;
i
++
)
for
(
i
=
0
;
i
<
SHA_DIGEST_LENGTH
;
i
++
)
...
@@ -1811,6 +1822,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
...
@@ -1811,6 +1822,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
*/
*/
if
(
!
c
->
save_config
(
c
,
NULL
))
if
(
!
c
->
save_config
(
c
,
NULL
))
ERROR
(
"Failed to save initial config for
\"
%s
\"
"
,
c
->
name
);
ERROR
(
"Failed to save initial config for
\"
%s
\"
"
,
c
->
name
);
ret
=
true
;
ret
=
true
;
goto
out
;
goto
out
;
}
}
...
@@ -1856,14 +1868,17 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
...
@@ -1856,14 +1868,17 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
bdev
->
ops
->
destroy
(
bdev
);
bdev
->
ops
->
destroy
(
bdev
);
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
_exit
(
EXIT_SUCCESS
);
_exit
(
EXIT_SUCCESS
);
}
}
if
(
wait_for_pid
(
pid
)
!=
0
)
if
(
wait_for_pid
(
pid
)
!=
0
)
goto
out_unlock
;
goto
out_unlock
;
/* Reload config to get the rootfs. */
/* Reload config to get the rootfs. */
lxc_conf_free
(
c
->
lxc_conf
);
lxc_conf_free
(
c
->
lxc_conf
);
c
->
lxc_conf
=
NULL
;
c
->
lxc_conf
=
NULL
;
if
(
!
load_config_locked
(
c
,
c
->
configfile
))
if
(
!
load_config_locked
(
c
,
c
->
configfile
))
goto
out_unlock
;
goto
out_unlock
;
...
@@ -1881,15 +1896,18 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
...
@@ -1881,15 +1896,18 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
goto
out_unlock
;
goto
out_unlock
;
}
}
}
}
ret
=
load_config_locked
(
c
,
c
->
configfile
);
ret
=
load_config_locked
(
c
,
c
->
configfile
);
out_unlock
:
out_unlock
:
umask
(
mask
);
umask
(
mask
);
if
(
partial_fd
>=
0
)
if
(
partial_fd
>=
0
)
remove_partial
(
c
,
partial_fd
);
remove_partial
(
c
,
partial_fd
);
out
:
out
:
if
(
!
ret
)
if
(
!
ret
)
container_destroy
(
c
,
NULL
);
container_destroy
(
c
,
NULL
);
free_tpath
:
free_tpath
:
free
(
tpath
);
free
(
tpath
);
return
ret
;
return
ret
;
...
@@ -1900,7 +1918,9 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
...
@@ -1900,7 +1918,9 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
int
flags
,
char
*
const
argv
[])
int
flags
,
char
*
const
argv
[])
{
{
bool
ret
;
bool
ret
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
ret
=
do_lxcapi_create
(
c
,
t
,
bdevtype
,
specs
,
flags
,
argv
);
ret
=
do_lxcapi_create
(
c
,
t
,
bdevtype
,
specs
,
flags
,
argv
);
current_config
=
NULL
;
current_config
=
NULL
;
return
ret
;
return
ret
;
...
@@ -1981,6 +2001,7 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
...
@@ -1981,6 +2001,7 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
if
(
killret
<
0
)
{
if
(
killret
<
0
)
{
if
(
state_client_fd
>=
0
)
if
(
state_client_fd
>=
0
)
close
(
state_client_fd
);
close
(
state_client_fd
);
WARN
(
"Failed to send signal %d to pid %d"
,
rebootsignal
,
pid
);
WARN
(
"Failed to send signal %d to pid %d"
,
rebootsignal
,
pid
);
return
false
;
return
false
;
}
}
...
@@ -2051,6 +2072,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
...
@@ -2051,6 +2072,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
if
(
killret
<
0
)
{
if
(
killret
<
0
)
{
if
(
state_client_fd
>=
0
)
if
(
state_client_fd
>=
0
)
close
(
state_client_fd
);
close
(
state_client_fd
);
WARN
(
"Failed to send signal %d to pid %d"
,
haltsignal
,
pid
);
WARN
(
"Failed to send signal %d to pid %d"
,
haltsignal
,
pid
);
return
false
;
return
false
;
}
}
...
@@ -2151,6 +2173,7 @@ static bool do_lxcapi_clear_config_item(struct lxc_container *c,
...
@@ -2151,6 +2173,7 @@ static bool do_lxcapi_clear_config_item(struct lxc_container *c,
*/
*/
if
(
config
&&
config
->
clr
)
if
(
config
&&
config
->
clr
)
ret
=
config
->
clr
(
key
,
c
->
lxc_conf
,
NULL
);
ret
=
config
->
clr
(
key
,
c
->
lxc_conf
,
NULL
);
if
(
!
ret
)
if
(
!
ret
)
do_clear_unexp_config_line
(
c
->
lxc_conf
,
key
);
do_clear_unexp_config_line
(
c
->
lxc_conf
,
key
);
...
@@ -2164,10 +2187,11 @@ static inline bool enter_net_ns(struct lxc_container *c)
...
@@ -2164,10 +2187,11 @@ static inline bool enter_net_ns(struct lxc_container *c)
{
{
pid_t
pid
=
do_lxcapi_init_pid
(
c
);
pid_t
pid
=
do_lxcapi_init_pid
(
c
);
if
((
geteuid
()
!=
0
||
(
c
->
lxc_conf
&&
!
lxc_list_empty
(
&
c
->
lxc_conf
->
id_map
)))
&&
access
(
"/proc/self/ns/user"
,
F_OK
)
==
0
)
{
if
((
geteuid
()
!=
0
||
(
c
->
lxc_conf
&&
!
lxc_list_empty
(
&
c
->
lxc_conf
->
id_map
)))
&&
(
access
(
"/proc/self/ns/user"
,
F_OK
)
==
0
))
if
(
!
switch_to_ns
(
pid
,
"user"
))
if
(
!
switch_to_ns
(
pid
,
"user"
))
return
false
;
return
false
;
}
return
switch_to_ns
(
pid
,
"net"
);
return
switch_to_ns
(
pid
,
"net"
);
}
}
...
@@ -2229,10 +2253,11 @@ static char** get_from_array(char ***names, char *cname, int size)
...
@@ -2229,10 +2253,11 @@ static char** get_from_array(char ***names, char *cname, int size)
return
(
char
**
)
bsearch
(
&
cname
,
*
names
,
size
,
sizeof
(
char
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
string_cmp
);
return
(
char
**
)
bsearch
(
&
cname
,
*
names
,
size
,
sizeof
(
char
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
string_cmp
);
}
}
static
bool
array_contains
(
char
***
names
,
char
*
cname
,
int
size
)
static
bool
array_contains
(
char
***
names
,
char
*
cname
,
int
size
)
{
{
if
(
get_from_array
(
names
,
cname
,
size
)
!=
NULL
)
if
(
get_from_array
(
names
,
cname
,
size
)
!=
NULL
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
...
@@ -2243,6 +2268,7 @@ static bool remove_from_array(char ***names, char *cname, int size)
...
@@ -2243,6 +2268,7 @@ static bool remove_from_array(char ***names, char *cname, int size)
free
(
result
);
free
(
result
);
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
...
@@ -2293,6 +2319,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
...
@@ -2293,6 +2319,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
}
}
count
++
;
count
++
;
}
}
ret
=
0
;
ret
=
0
;
out
:
out
:
...
@@ -2322,6 +2349,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
...
@@ -2322,6 +2349,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
if
(
wait_for_pid
(
pid
)
!=
0
)
{
if
(
wait_for_pid
(
pid
)
!=
0
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
for
(
i
=
0
;
i
<
count
;
i
++
)
free
(
interfaces
[
i
]);
free
(
interfaces
[
i
]);
free
(
interfaces
);
free
(
interfaces
);
interfaces
=
NULL
;
interfaces
=
NULL
;
}
}
...
@@ -2422,8 +2450,10 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
...
@@ -2422,8 +2450,10 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
address
);
address
);
goto
out
;
goto
out
;
}
}
count
++
;
count
++
;
}
}
ret
=
0
;
ret
=
0
;
out
:
out
:
...
@@ -2497,8 +2527,10 @@ static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const ch
...
@@ -2497,8 +2527,10 @@ static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const ch
if
(
!
c
||
!
c
->
lxc_conf
)
if
(
!
c
||
!
c
->
lxc_conf
)
return
NULL
;
return
NULL
;
if
(
container_mem_lock
(
c
))
if
(
container_mem_lock
(
c
))
return
NULL
;
return
NULL
;
ret
=
lxc_cmd_get_config_item
(
c
->
name
,
key
,
do_lxcapi_get_config_path
(
c
));
ret
=
lxc_cmd_get_config_item
(
c
->
name
,
key
,
do_lxcapi_get_config_path
(
c
));
container_mem_unlock
(
c
);
container_mem_unlock
(
c
);
return
ret
;
return
ret
;
...
@@ -2542,6 +2574,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file)
...
@@ -2542,6 +2574,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file)
if
(
!
alt_file
)
if
(
!
alt_file
)
alt_file
=
c
->
configfile
;
alt_file
=
c
->
configfile
;
if
(
!
alt_file
)
if
(
!
alt_file
)
return
false
;
return
false
;
...
@@ -2615,6 +2648,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
...
@@ -2615,6 +2648,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"%s/%s/lxc_snapshots"
,
c0
->
config_path
,
c0
->
name
);
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"%s/%s/lxc_snapshots"
,
c0
->
config_path
,
c0
->
name
);
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
goto
out
;
goto
out
;
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s
\n
%s
\n
"
,
c
->
config_path
,
c
->
name
);
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s
\n
%s
\n
"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
goto
out
;
goto
out
;
...
@@ -2702,6 +2736,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
...
@@ -2702,6 +2736,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
goto
out
;
goto
out
;
}
}
}
}
close
(
fd
);
close
(
fd
);
}
}
...
@@ -2737,9 +2772,11 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
...
@@ -2737,9 +2772,11 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
ERROR
(
"Path name too long"
);
ERROR
(
"Path name too long"
);
return
;
return
;
}
}
f
=
fopen
(
path
,
"r"
);
f
=
fopen
(
path
,
"r"
);
if
(
f
==
NULL
)
if
(
f
==
NULL
)
return
;
return
;
while
(
getline
(
&
lxcpath
,
&
pathlen
,
f
)
!=
-
1
)
{
while
(
getline
(
&
lxcpath
,
&
pathlen
,
f
)
!=
-
1
)
{
if
(
getline
(
&
lxcname
,
&
namelen
,
f
)
==
-
1
)
{
if
(
getline
(
&
lxcname
,
&
namelen
,
f
)
==
-
1
)
{
ERROR
(
"badly formatted file %s"
,
path
);
ERROR
(
"badly formatted file %s"
,
path
);
...
@@ -2754,11 +2791,14 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
...
@@ -2754,11 +2791,14 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
lxcpath
,
lxcname
);
lxcpath
,
lxcname
);
continue
;
continue
;
}
}
if
(
!
mod_rdep
(
p
,
c
,
inc
))
if
(
!
mod_rdep
(
p
,
c
,
inc
))
ERROR
(
"Failed to update snapshots file for %s:%s"
,
ERROR
(
"Failed to update snapshots file for %s:%s"
,
lxcpath
,
lxcname
);
lxcpath
,
lxcname
);
lxc_container_put
(
p
);
lxc_container_put
(
p
);
}
}
out
:
out
:
free
(
lxcpath
);
free
(
lxcpath
);
free
(
lxcname
);
free
(
lxcname
);
...
@@ -2777,20 +2817,24 @@ static bool has_fs_snapshots(struct lxc_container *c)
...
@@ -2777,20 +2817,24 @@ static bool has_fs_snapshots(struct lxc_container *c)
c
->
name
);
c
->
name
);
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
goto
out
;
goto
out
;
/* If the file doesn't exist there are no snapshots. */
/* If the file doesn't exist there are no snapshots. */
if
(
stat
(
path
,
&
fbuf
)
<
0
)
if
(
stat
(
path
,
&
fbuf
)
<
0
)
goto
out
;
goto
out
;
v
=
fbuf
.
st_size
;
v
=
fbuf
.
st_size
;
if
(
v
!=
0
)
{
if
(
v
!=
0
)
{
f
=
fopen
(
path
,
"r"
);
f
=
fopen
(
path
,
"r"
);
if
(
!
f
)
if
(
!
f
)
goto
out
;
goto
out
;
ret
=
fscanf
(
f
,
"%d"
,
&
v
);
ret
=
fscanf
(
f
,
"%d"
,
&
v
);
fclose
(
f
);
fclose
(
f
);
/* TODO: Figure out what to do with the return value of fscanf. */
/* TODO: Figure out what to do with the return value of fscanf. */
if
(
ret
!=
1
)
if
(
ret
!=
1
)
INFO
(
"Container uses new lxc-snapshots format %s"
,
path
);
INFO
(
"Container uses new lxc-snapshots format %s"
,
path
);
}
}
bret
=
v
!=
0
;
bret
=
v
!=
0
;
out
:
out
:
...
@@ -2806,9 +2850,11 @@ static bool has_snapshots(struct lxc_container *c)
...
@@ -2806,9 +2850,11 @@ static bool has_snapshots(struct lxc_container *c)
if
(
!
get_snappath_dir
(
c
,
path
))
if
(
!
get_snappath_dir
(
c
,
path
))
return
false
;
return
false
;
dir
=
opendir
(
path
);
dir
=
opendir
(
path
);
if
(
!
dir
)
if
(
!
dir
)
return
false
;
return
false
;
while
((
direntp
=
readdir
(
dir
)))
{
while
((
direntp
=
readdir
(
dir
)))
{
if
(
!
strcmp
(
direntp
->
d_name
,
"."
))
if
(
!
strcmp
(
direntp
->
d_name
,
"."
))
continue
;
continue
;
...
@@ -2818,6 +2864,7 @@ static bool has_snapshots(struct lxc_container *c)
...
@@ -2818,6 +2864,7 @@ static bool has_snapshots(struct lxc_container *c)
count
++
;
count
++
;
break
;
break
;
}
}
closedir
(
dir
);
closedir
(
dir
);
return
count
>
0
;
return
count
>
0
;
}
}
...
@@ -2901,6 +2948,7 @@ static bool container_destroy(struct lxc_container *c,
...
@@ -2901,6 +2948,7 @@ static bool container_destroy(struct lxc_container *c,
if
(
current_config
&&
conf
==
current_config
)
{
if
(
current_config
&&
conf
==
current_config
)
{
current_config
=
NULL
;
current_config
=
NULL
;
if
(
conf
->
logfd
!=
-
1
)
{
if
(
conf
->
logfd
!=
-
1
)
{
close
(
conf
->
logfd
);
close
(
conf
->
logfd
);
conf
->
logfd
=
-
1
;
conf
->
logfd
=
-
1
;
...
@@ -2966,6 +3014,7 @@ static bool container_destroy(struct lxc_container *c,
...
@@ -2966,6 +3014,7 @@ static bool container_destroy(struct lxc_container *c,
ret
=
snprintf
(
path
,
len
,
"%s/%s"
,
p1
,
c
->
name
);
ret
=
snprintf
(
path
,
len
,
"%s/%s"
,
p1
,
c
->
name
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
goto
out
;
goto
out
;
if
(
am_guest_unpriv
())
if
(
am_guest_unpriv
())
ret
=
userns_exec_full
(
conf
,
lxc_rmdir_onedev_wrapper
,
path
,
ret
=
userns_exec_full
(
conf
,
lxc_rmdir_onedev_wrapper
,
path
,
"lxc_rmdir_onedev_wrapper"
);
"lxc_rmdir_onedev_wrapper"
);
...
@@ -2983,6 +3032,7 @@ static bool container_destroy(struct lxc_container *c,
...
@@ -2983,6 +3032,7 @@ static bool container_destroy(struct lxc_container *c,
out
:
out
:
if
(
path
)
if
(
path
)
free
(
path
);
free
(
path
);
container_disk_unlock
(
c
);
container_disk_unlock
(
c
);
return
bret
;
return
bret
;
}
}
...
@@ -3011,10 +3061,12 @@ static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c)
...
@@ -3011,10 +3061,12 @@ static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c)
{
{
if
(
!
c
||
!
lxcapi_is_defined
(
c
))
if
(
!
c
||
!
lxcapi_is_defined
(
c
))
return
false
;
return
false
;
if
(
!
lxcapi_snapshot_destroy_all
(
c
))
{
if
(
!
lxcapi_snapshot_destroy_all
(
c
))
{
ERROR
(
"Error deleting all snapshots"
);
ERROR
(
"Error deleting all snapshots"
);
return
false
;
return
false
;
}
}
return
lxcapi_destroy
(
c
);
return
lxcapi_destroy
(
c
);
}
}
...
@@ -3085,6 +3137,7 @@ static char *lxcapi_config_file_name(struct lxc_container *c)
...
@@ -3085,6 +3137,7 @@ static char *lxcapi_config_file_name(struct lxc_container *c)
{
{
if
(
!
c
||
!
c
->
configfile
)
if
(
!
c
||
!
c
->
configfile
)
return
NULL
;
return
NULL
;
return
strdup
(
c
->
configfile
);
return
strdup
(
c
->
configfile
);
}
}
...
@@ -3092,6 +3145,7 @@ static const char *lxcapi_get_config_path(struct lxc_container *c)
...
@@ -3092,6 +3145,7 @@ static const char *lxcapi_get_config_path(struct lxc_container *c)
{
{
if
(
!
c
||
!
c
->
config_path
)
if
(
!
c
||
!
c
->
config_path
)
return
NULL
;
return
NULL
;
return
(
const
char
*
)(
c
->
config_path
);
return
(
const
char
*
)(
c
->
config_path
);
}
}
...
@@ -3160,6 +3214,7 @@ static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path)
...
@@ -3160,6 +3214,7 @@ static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path)
c
->
config_path
=
oldpath
;
c
->
config_path
=
oldpath
;
oldpath
=
NULL
;
oldpath
=
NULL
;
}
}
err
:
err
:
free
(
oldpath
);
free
(
oldpath
);
container_mem_unlock
(
c
);
container_mem_unlock
(
c
);
...
@@ -3248,6 +3303,7 @@ static int copy_file(const char *old, const char *new)
...
@@ -3248,6 +3303,7 @@ static int copy_file(const char *old, const char *new)
ERROR
(
"copy destination %s exists"
,
new
);
ERROR
(
"copy destination %s exists"
,
new
);
return
-
1
;
return
-
1
;
}
}
ret
=
stat
(
old
,
&
sbuf
);
ret
=
stat
(
old
,
&
sbuf
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
INFO
(
"Error stat'ing %s"
,
old
);
INFO
(
"Error stat'ing %s"
,
old
);
...
@@ -3259,6 +3315,7 @@ static int copy_file(const char *old, const char *new)
...
@@ -3259,6 +3315,7 @@ static int copy_file(const char *old, const char *new)
SYSERROR
(
"Error opening original file %s"
,
old
);
SYSERROR
(
"Error opening original file %s"
,
old
);
return
-
1
;
return
-
1
;
}
}
out
=
open
(
new
,
O_CREAT
|
O_EXCL
|
O_WRONLY
,
0644
);
out
=
open
(
new
,
O_CREAT
|
O_EXCL
|
O_WRONLY
,
0644
);
if
(
out
<
0
)
{
if
(
out
<
0
)
{
SYSERROR
(
"Error opening new file %s"
,
new
);
SYSERROR
(
"Error opening new file %s"
,
new
);
...
@@ -3272,14 +3329,17 @@ static int copy_file(const char *old, const char *new)
...
@@ -3272,14 +3329,17 @@ static int copy_file(const char *old, const char *new)
SYSERROR
(
"Error reading old file %s"
,
old
);
SYSERROR
(
"Error reading old file %s"
,
old
);
goto
err
;
goto
err
;
}
}
if
(
len
==
0
)
if
(
len
==
0
)
break
;
break
;
ret
=
write
(
out
,
buf
,
len
);
ret
=
write
(
out
,
buf
,
len
);
if
(
ret
<
len
)
{
/* should we retry? */
if
(
ret
<
len
)
{
/* should we retry? */
SYSERROR
(
"Error: write to new file %s was interrupted"
,
new
);
SYSERROR
(
"Error: write to new file %s was interrupted"
,
new
);
goto
err
;
goto
err
;
}
}
}
}
close
(
in
);
close
(
in
);
close
(
out
);
close
(
out
);
...
@@ -3317,19 +3377,24 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
...
@@ -3317,19 +3377,24 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
char
tmppath
[
MAXPATHLEN
];
char
tmppath
[
MAXPATHLEN
];
if
(
!
fname
)
/* relative path - we don't support, but maybe we should */
if
(
!
fname
)
/* relative path - we don't support, but maybe we should */
return
0
;
return
0
;
if
(
strncmp
(
hookname
,
cpath
,
len
-
1
)
!=
0
)
{
if
(
strncmp
(
hookname
,
cpath
,
len
-
1
)
!=
0
)
{
/* this hook is public - ignore */
/* this hook is public - ignore */
continue
;
continue
;
}
}
/* copy the script, and change the entry in confile */
/* copy the script, and change the entry in confile */
ret
=
snprintf
(
tmppath
,
MAXPATHLEN
,
"%s/%s/%s"
,
ret
=
snprintf
(
tmppath
,
MAXPATHLEN
,
"%s/%s/%s"
,
c
->
config_path
,
c
->
name
,
fname
+
1
);
c
->
config_path
,
c
->
name
,
fname
+
1
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
-
1
;
return
-
1
;
ret
=
copy_file
(
it
->
elem
,
tmppath
);
ret
=
copy_file
(
it
->
elem
,
tmppath
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
free
(
it
->
elem
);
free
(
it
->
elem
);
it
->
elem
=
strdup
(
tmppath
);
it
->
elem
=
strdup
(
tmppath
);
if
(
!
it
->
elem
)
{
if
(
!
it
->
elem
)
{
ERROR
(
"out of memory copying hook path"
);
ERROR
(
"out of memory copying hook path"
);
...
@@ -3343,6 +3408,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
...
@@ -3343,6 +3408,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
ERROR
(
"Error saving new hooks in clone"
);
ERROR
(
"Error saving new hooks in clone"
);
return
-
1
;
return
-
1
;
}
}
do_lxcapi_save_config
(
c
,
NULL
);
do_lxcapi_save_config
(
c
,
NULL
);
return
0
;
return
0
;
}
}
...
@@ -3362,12 +3428,14 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
...
@@ -3362,12 +3428,14 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
char
*
p
=
strrchr
(
oldpath
,
'/'
);
char
*
p
=
strrchr
(
oldpath
,
'/'
);
if
(
!
p
)
if
(
!
p
)
return
-
1
;
return
-
1
;
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s/%s%s"
,
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s/%s%s"
,
c
->
config_path
,
c
->
name
,
p
);
c
->
config_path
,
c
->
name
,
p
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
ERROR
(
"error printing new path for %s"
,
oldpath
);
ERROR
(
"error printing new path for %s"
,
oldpath
);
return
-
1
;
return
-
1
;
}
}
if
(
file_exists
(
newpath
))
{
if
(
file_exists
(
newpath
))
{
ERROR
(
"error: fstab file %s exists"
,
newpath
);
ERROR
(
"error: fstab file %s exists"
,
newpath
);
return
-
1
;
return
-
1
;
...
@@ -3377,12 +3445,15 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
...
@@ -3377,12 +3445,15 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
ERROR
(
"error: copying %s to %s"
,
oldpath
,
newpath
);
ERROR
(
"error: copying %s to %s"
,
oldpath
,
newpath
);
return
-
1
;
return
-
1
;
}
}
free
(
c
->
lxc_conf
->
fstab
);
free
(
c
->
lxc_conf
->
fstab
);
c
->
lxc_conf
->
fstab
=
strdup
(
newpath
);
c
->
lxc_conf
->
fstab
=
strdup
(
newpath
);
if
(
!
c
->
lxc_conf
->
fstab
)
{
if
(
!
c
->
lxc_conf
->
fstab
)
{
ERROR
(
"error: allocating pathname"
);
ERROR
(
"error: allocating pathname"
);
return
-
1
;
return
-
1
;
}
}
if
(
!
do_append_unexp_config_line
(
c
->
lxc_conf
,
"lxc.mount.fstab"
,
newpath
))
{
if
(
!
do_append_unexp_config_line
(
c
->
lxc_conf
,
"lxc.mount.fstab"
,
newpath
))
{
ERROR
(
"error saving new lxctab"
);
ERROR
(
"error saving new lxctab"
);
return
-
1
;
return
-
1
;
...
@@ -3402,12 +3473,14 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
...
@@ -3402,12 +3473,14 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
WARN
(
"Error copying reverse dependencies"
);
WARN
(
"Error copying reverse dependencies"
);
return
;
return
;
}
}
ret
=
snprintf
(
path1
,
MAXPATHLEN
,
"%s/%s/lxc_rdepends"
,
c
->
config_path
,
ret
=
snprintf
(
path1
,
MAXPATHLEN
,
"%s/%s/lxc_rdepends"
,
c
->
config_path
,
c
->
name
);
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
WARN
(
"Error copying reverse dependencies"
);
WARN
(
"Error copying reverse dependencies"
);
return
;
return
;
}
}
if
(
copy_file
(
path0
,
path1
)
<
0
)
{
if
(
copy_file
(
path0
,
path1
)
<
0
)
{
INFO
(
"Error copying reverse dependencies"
);
INFO
(
"Error copying reverse dependencies"
);
return
;
return
;
...
@@ -3425,15 +3498,20 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
...
@@ -3425,15 +3498,20 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
c
->
name
);
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
return
false
;
f
=
fopen
(
path
,
"a"
);
f
=
fopen
(
path
,
"a"
);
if
(
!
f
)
if
(
!
f
)
return
false
;
return
false
;
bret
=
true
;
bret
=
true
;
/* If anything goes wrong, just return an error. */
/* If anything goes wrong, just return an error. */
if
(
fprintf
(
f
,
"%s
\n
%s
\n
"
,
c0
->
config_path
,
c0
->
name
)
<
0
)
if
(
fprintf
(
f
,
"%s
\n
%s
\n
"
,
c0
->
config_path
,
c0
->
name
)
<
0
)
bret
=
false
;
bret
=
false
;
if
(
fclose
(
f
)
!=
0
)
if
(
fclose
(
f
)
!=
0
)
bret
=
false
;
bret
=
false
;
return
bret
;
return
bret
;
}
}
...
@@ -3506,6 +3584,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
...
@@ -3506,6 +3584,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
if
(
flags
&
LXC_CLONE_SNAPSHOT
)
if
(
flags
&
LXC_CLONE_SNAPSHOT
)
copy_rdepends
(
c
,
c0
);
copy_rdepends
(
c
,
c0
);
if
(
need_rdep
)
{
if
(
need_rdep
)
{
if
(
!
add_rdepends
(
c
,
c0
))
if
(
!
add_rdepends
(
c
,
c0
))
WARN
(
"Error adding reverse dependency from %s to %s"
,
WARN
(
"Error adding reverse dependency from %s to %s"
,
...
@@ -3543,30 +3622,36 @@ static int clone_update_rootfs(struct clone_update_data *data)
...
@@ -3543,30 +3622,36 @@ static int clone_update_rootfs(struct clone_update_data *data)
ERROR
(
"Failed to setgid to 0"
);
ERROR
(
"Failed to setgid to 0"
);
return
-
1
;
return
-
1
;
}
}
if
(
setuid
(
0
)
<
0
)
{
if
(
setuid
(
0
)
<
0
)
{
ERROR
(
"Failed to setuid to 0"
);
ERROR
(
"Failed to setuid to 0"
);
return
-
1
;
return
-
1
;
}
}
if
(
setgroups
(
0
,
NULL
)
<
0
)
if
(
setgroups
(
0
,
NULL
)
<
0
)
WARN
(
"Failed to clear groups"
);
WARN
(
"Failed to clear groups"
);
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
return
-
1
;
return
-
1
;
bdev
=
storage_init
(
c
->
lxc_conf
);
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
if
(
!
bdev
)
return
-
1
;
return
-
1
;
if
(
strcmp
(
bdev
->
type
,
"dir"
)
!=
0
)
{
if
(
strcmp
(
bdev
->
type
,
"dir"
)
!=
0
)
{
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
{
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
{
ERROR
(
"error unsharing mounts"
);
ERROR
(
"error unsharing mounts"
);
storage_put
(
bdev
);
storage_put
(
bdev
);
return
-
1
;
return
-
1
;
}
}
if
(
detect_shared_rootfs
())
{
if
(
detect_shared_rootfs
())
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
SYSERROR
(
"Failed to make / rslave"
);
SYSERROR
(
"Failed to make / rslave"
);
ERROR
(
"Continuing..."
);
ERROR
(
"Continuing..."
);
}
}
}
}
if
(
bdev
->
ops
->
mount
(
bdev
)
<
0
)
{
if
(
bdev
->
ops
->
mount
(
bdev
)
<
0
)
{
storage_put
(
bdev
);
storage_put
(
bdev
);
return
-
1
;
return
-
1
;
...
@@ -3578,21 +3663,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
...
@@ -3578,21 +3663,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if
(
!
lxc_list_empty
(
&
conf
->
hooks
[
LXCHOOK_CLONE
]))
{
if
(
!
lxc_list_empty
(
&
conf
->
hooks
[
LXCHOOK_CLONE
]))
{
/* Start of environment variable setup for hooks */
/* Start of environment variable setup for hooks */
if
(
c0
->
name
&&
setenv
(
"LXC_SRC_NAME"
,
c0
->
name
,
1
))
{
if
(
c0
->
name
&&
setenv
(
"LXC_SRC_NAME"
,
c0
->
name
,
1
))
SYSERROR
(
"failed to set environment variable for source container name"
);
SYSERROR
(
"failed to set environment variable for source container name"
);
}
if
(
setenv
(
"LXC_NAME"
,
c
->
name
,
1
))
{
if
(
setenv
(
"LXC_NAME"
,
c
->
name
,
1
))
SYSERROR
(
"failed to set environment variable for container name"
);
SYSERROR
(
"failed to set environment variable for container name"
);
}
if
(
conf
->
rcfile
&&
setenv
(
"LXC_CONFIG_FILE"
,
conf
->
rcfile
,
1
))
{
if
(
conf
->
rcfile
&&
setenv
(
"LXC_CONFIG_FILE"
,
conf
->
rcfile
,
1
))
SYSERROR
(
"failed to set environment variable for config path"
);
SYSERROR
(
"failed to set environment variable for config path"
);
}
if
(
bdev
->
dest
&&
setenv
(
"LXC_ROOTFS_MOUNT"
,
bdev
->
dest
,
1
))
{
if
(
bdev
->
dest
&&
setenv
(
"LXC_ROOTFS_MOUNT"
,
bdev
->
dest
,
1
))
SYSERROR
(
"failed to set environment variable for rootfs mount"
);
SYSERROR
(
"failed to set environment variable for rootfs mount"
);
}
if
(
conf
->
rootfs
.
path
&&
setenv
(
"LXC_ROOTFS_PATH"
,
conf
->
rootfs
.
path
,
1
))
{
if
(
conf
->
rootfs
.
path
&&
setenv
(
"LXC_ROOTFS_PATH"
,
conf
->
rootfs
.
path
,
1
))
SYSERROR
(
"failed to set environment variable for rootfs mount"
);
SYSERROR
(
"failed to set environment variable for rootfs mount"
);
}
if
(
run_lxc_hooks
(
c
->
name
,
"clone"
,
conf
,
hookargs
))
{
if
(
run_lxc_hooks
(
c
->
name
,
"clone"
,
conf
,
hookargs
))
{
ERROR
(
"Error executing clone hook for %s"
,
c
->
name
);
ERROR
(
"Error executing clone hook for %s"
,
c
->
name
);
...
@@ -3607,16 +3691,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
...
@@ -3607,16 +3691,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
-
1
;
return
-
1
;
if
(
!
file_exists
(
path
))
if
(
!
file_exists
(
path
))
return
0
;
return
0
;
if
(
!
(
fout
=
fopen
(
path
,
"w"
)))
{
if
(
!
(
fout
=
fopen
(
path
,
"w"
)))
{
SYSERROR
(
"unable to open %s: ignoring"
,
path
);
SYSERROR
(
"unable to open %s: ignoring"
,
path
);
return
0
;
return
0
;
}
}
if
(
fprintf
(
fout
,
"%s"
,
c
->
name
)
<
0
)
{
if
(
fprintf
(
fout
,
"%s"
,
c
->
name
)
<
0
)
{
fclose
(
fout
);
fclose
(
fout
);
return
-
1
;
return
-
1
;
}
}
if
(
fclose
(
fout
)
<
0
)
if
(
fclose
(
fout
)
<
0
)
return
-
1
;
return
-
1
;
}
else
{
}
else
{
...
@@ -3650,9 +3738,11 @@ static int create_file_dirname(char *path, struct lxc_conf *conf)
...
@@ -3650,9 +3738,11 @@ static int create_file_dirname(char *path, struct lxc_conf *conf)
if
(
!
p
)
if
(
!
p
)
return
-
1
;
return
-
1
;
*
p
=
'\0'
;
*
p
=
'\0'
;
ret
=
do_create_container_dir
(
path
,
conf
);
ret
=
do_create_container_dir
(
path
,
conf
);
*
p
=
'/'
;
*
p
=
'/'
;
return
ret
;
return
ret
;
}
}
...
@@ -3684,8 +3774,10 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
...
@@ -3684,8 +3774,10 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
/* Make sure the container doesn't yet exist. */
/* Make sure the container doesn't yet exist. */
if
(
!
newname
)
if
(
!
newname
)
newname
=
c
->
name
;
newname
=
c
->
name
;
if
(
!
lxcpath
)
if
(
!
lxcpath
)
lxcpath
=
do_lxcapi_get_config_path
(
c
);
lxcpath
=
do_lxcapi_get_config_path
(
c
);
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s/%s/config"
,
lxcpath
,
newname
);
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s/%s/config"
,
lxcpath
,
newname
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
SYSERROR
(
"clone: failed making config pathname"
);
SYSERROR
(
"clone: failed making config pathname"
);
...
@@ -3727,7 +3819,9 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
...
@@ -3727,7 +3819,9 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
clear_unexp_config_line
(
c
->
lxc_conf
,
"lxc.rootfs.path"
,
false
);
clear_unexp_config_line
(
c
->
lxc_conf
,
"lxc.rootfs.path"
,
false
);
write_config
(
fd
,
c
->
lxc_conf
);
write_config
(
fd
,
c
->
lxc_conf
);
close
(
fd
);
close
(
fd
);
c
->
lxc_conf
->
rootfs
.
path
=
origroot
;
c
->
lxc_conf
->
rootfs
.
path
=
origroot
;
free
(
c
->
lxc_conf
->
unexpanded_config
);
free
(
c
->
lxc_conf
->
unexpanded_config
);
c
->
lxc_conf
->
unexpanded_config
=
saved_unexp_conf
;
c
->
lxc_conf
->
unexpanded_config
=
saved_unexp_conf
;
saved_unexp_conf
=
NULL
;
saved_unexp_conf
=
NULL
;
...
@@ -3771,7 +3865,6 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
...
@@ -3771,7 +3865,6 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
out
;
goto
out
;
/* update utsname */
/* update utsname */
if
(
!
(
flags
&
LXC_CLONE_KEEPNAME
))
{
if
(
!
(
flags
&
LXC_CLONE_KEEPNAME
))
{
clear_unexp_config_line
(
c2
->
lxc_conf
,
"lxc.utsname"
,
false
);
clear_unexp_config_line
(
c2
->
lxc_conf
,
"lxc.utsname"
,
false
);
...
@@ -3819,17 +3912,21 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
...
@@ -3819,17 +3912,21 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
SYSERROR
(
"fork"
);
SYSERROR
(
"fork"
);
goto
out
;
goto
out
;
}
}
if
(
pid
>
0
)
{
if
(
pid
>
0
)
{
ret
=
wait_for_pid
(
pid
);
ret
=
wait_for_pid
(
pid
);
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
container_mem_unlock
(
c
);
container_mem_unlock
(
c
);
return
c2
;
return
c2
;
}
}
data
.
c0
=
c
;
data
.
c0
=
c
;
data
.
c1
=
c2
;
data
.
c1
=
c2
;
data
.
flags
=
flags
;
data
.
flags
=
flags
;
data
.
hookargs
=
hookargs
;
data
.
hookargs
=
hookargs
;
if
(
am_guest_unpriv
())
if
(
am_guest_unpriv
())
ret
=
userns_exec_full
(
c
->
lxc_conf
,
clone_update_rootfs_wrapper
,
ret
=
userns_exec_full
(
c
->
lxc_conf
,
clone_update_rootfs_wrapper
,
&
data
,
"clone_update_rootfs_wrapper"
);
&
data
,
"clone_update_rootfs_wrapper"
);
...
@@ -3846,6 +3943,7 @@ out:
...
@@ -3846,6 +3943,7 @@ out:
if
(
c2
)
{
if
(
c2
)
{
if
(
!
storage_copied
)
if
(
!
storage_copied
)
c2
->
lxc_conf
->
rootfs
.
path
=
NULL
;
c2
->
lxc_conf
->
rootfs
.
path
=
NULL
;
c2
->
destroy
(
c2
);
c2
->
destroy
(
c2
);
lxc_container_put
(
c2
);
lxc_container_put
(
c2
);
}
}
...
@@ -3859,9 +3957,11 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
...
@@ -3859,9 +3957,11 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
char
**
hookargs
)
char
**
hookargs
)
{
{
struct
lxc_container
*
ret
;
struct
lxc_container
*
ret
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
ret
=
do_lxcapi_clone
(
c
,
newname
,
lxcpath
,
flags
,
bdevtype
,
bdevdata
,
newsize
,
hookargs
);
ret
=
do_lxcapi_clone
(
c
,
newname
,
lxcpath
,
flags
,
bdevtype
,
bdevdata
,
newsize
,
hookargs
);
current_config
=
NULL
;
current_config
=
NULL
;
return
ret
;
return
ret
;
}
}
...
@@ -3877,6 +3977,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
...
@@ -3877,6 +3977,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
ERROR
(
"Renaming a container with snapshots is not supported"
);
ERROR
(
"Renaming a container with snapshots is not supported"
);
return
false
;
return
false
;
}
}
bdev
=
storage_init
(
c
->
lxc_conf
);
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
{
if
(
!
bdev
)
{
ERROR
(
"Failed to find original backing store type"
);
ERROR
(
"Failed to find original backing store type"
);
...
@@ -3897,6 +3998,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
...
@@ -3897,6 +3998,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
ERROR
(
"Could not destroy existing container %s"
,
c
->
name
);
ERROR
(
"Could not destroy existing container %s"
,
c
->
name
);
return
false
;
return
false
;
}
}
return
true
;
return
true
;
}
}
...
@@ -3927,20 +4029,24 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options
...
@@ -3927,20 +4029,24 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options
command
.
program
=
(
char
*
)
program
;
command
.
program
=
(
char
*
)
program
;
command
.
argv
=
(
char
**
)
argv
;
command
.
argv
=
(
char
**
)
argv
;
r
=
lxc_attach
(
c
->
name
,
c
->
config_path
,
lxc_attach_run_command
,
&
command
,
options
,
&
pid
);
r
=
lxc_attach
(
c
->
name
,
c
->
config_path
,
lxc_attach_run_command
,
&
command
,
options
,
&
pid
);
if
(
r
<
0
)
{
if
(
r
<
0
)
{
ERROR
(
"ups"
);
ERROR
(
"ups"
);
return
r
;
return
r
;
}
}
return
lxc_wait_for_pid_status
(
pid
);
return
lxc_wait_for_pid_status
(
pid
);
}
}
static
int
lxcapi_attach_run_wait
(
struct
lxc_container
*
c
,
lxc_attach_options_t
*
options
,
const
char
*
program
,
const
char
*
const
argv
[])
static
int
lxcapi_attach_run_wait
(
struct
lxc_container
*
c
,
lxc_attach_options_t
*
options
,
const
char
*
program
,
const
char
*
const
argv
[])
{
{
int
ret
;
int
ret
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
ret
=
do_lxcapi_attach_run_wait
(
c
,
options
,
program
,
argv
);
ret
=
do_lxcapi_attach_run_wait
(
c
,
options
,
program
,
argv
);
current_config
=
NULL
;
current_config
=
NULL
;
return
ret
;
return
ret
;
}
}
...
@@ -3951,11 +4057,14 @@ static int get_next_index(const char *lxcpath, char *cname)
...
@@ -3951,11 +4057,14 @@ static int get_next_index(const char *lxcpath, char *cname)
int
i
=
0
,
ret
;
int
i
=
0
,
ret
;
fname
=
alloca
(
strlen
(
lxcpath
)
+
20
);
fname
=
alloca
(
strlen
(
lxcpath
)
+
20
);
while
(
1
)
{
while
(
1
)
{
sprintf
(
fname
,
"%s/snap%d"
,
lxcpath
,
i
);
sprintf
(
fname
,
"%s/snap%d"
,
lxcpath
,
i
);
ret
=
stat
(
fname
,
&
sb
);
ret
=
stat
(
fname
,
&
sb
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
return
i
;
return
i
;
i
++
;
i
++
;
}
}
}
}
...
@@ -3963,6 +4072,7 @@ static int get_next_index(const char *lxcpath, char *cname)
...
@@ -3963,6 +4072,7 @@ static int get_next_index(const char *lxcpath, char *cname)
static
bool
get_snappath_dir
(
struct
lxc_container
*
c
,
char
*
snappath
)
static
bool
get_snappath_dir
(
struct
lxc_container
*
c
,
char
*
snappath
)
{
{
int
ret
;
int
ret
;
/*
/*
* If the old style snapshot path exists, use it
* If the old style snapshot path exists, use it
* /var/lib/lxc -> /var/lib/lxcsnaps
* /var/lib/lxc -> /var/lib/lxcsnaps
...
@@ -3970,10 +4080,12 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
...
@@ -3970,10 +4080,12 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%ssnaps"
,
c
->
config_path
);
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%ssnaps"
,
c
->
config_path
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
return
false
;
if
(
dir_exists
(
snappath
))
{
if
(
dir_exists
(
snappath
))
{
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%ssnaps/%s"
,
c
->
config_path
,
c
->
name
);
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%ssnaps/%s"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
return
false
;
return
true
;
return
true
;
}
}
...
@@ -3984,6 +4096,7 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
...
@@ -3984,6 +4096,7 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%s/%s/snaps"
,
c
->
config_path
,
c
->
name
);
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%s/%s/snaps"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
return
false
;
return
true
;
return
true
;
}
}
...
@@ -4029,6 +4142,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
...
@@ -4029,6 +4142,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
ERROR
(
"and keep the original container pristine."
);
ERROR
(
"and keep the original container pristine."
);
flags
&=
~
LXC_CLONE_SNAPSHOT
|
LXC_CLONE_MAYBE_SNAPSHOT
;
flags
&=
~
LXC_CLONE_SNAPSHOT
|
LXC_CLONE_MAYBE_SNAPSHOT
;
}
}
c2
=
do_lxcapi_clone
(
c
,
newname
,
snappath
,
flags
,
NULL
,
NULL
,
0
,
NULL
);
c2
=
do_lxcapi_clone
(
c
,
newname
,
snappath
,
flags
,
NULL
,
NULL
,
0
,
NULL
);
if
(
!
c2
)
{
if
(
!
c2
)
{
ERROR
(
"clone of %s:%s failed"
,
c
->
config_path
,
c
->
name
);
ERROR
(
"clone of %s:%s failed"
,
c
->
config_path
,
c
->
name
);
...
@@ -4055,11 +4169,13 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
...
@@ -4055,11 +4169,13 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
ERROR
(
"Failed to open %s"
,
dfnam
);
ERROR
(
"Failed to open %s"
,
dfnam
);
return
-
1
;
return
-
1
;
}
}
if
(
fprintf
(
f
,
"%s"
,
buffer
)
<
0
)
{
if
(
fprintf
(
f
,
"%s"
,
buffer
)
<
0
)
{
SYSERROR
(
"Writing timestamp"
);
SYSERROR
(
"Writing timestamp"
);
fclose
(
f
);
fclose
(
f
);
return
-
1
;
return
-
1
;
}
}
ret
=
fclose
(
f
);
ret
=
fclose
(
f
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
SYSERROR
(
"Writing timestamp"
);
SYSERROR
(
"Writing timestamp"
);
...
@@ -4070,6 +4186,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
...
@@ -4070,6 +4186,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
/* $p / $name / comment \0 */
/* $p / $name / comment \0 */
int
len
=
strlen
(
snappath
)
+
strlen
(
newname
)
+
10
;
int
len
=
strlen
(
snappath
)
+
strlen
(
newname
)
+
10
;
char
*
path
=
alloca
(
len
);
char
*
path
=
alloca
(
len
);
sprintf
(
path
,
"%s/%s/comment"
,
snappath
,
newname
);
sprintf
(
path
,
"%s/%s/comment"
,
snappath
,
newname
);
return
copy_file
(
commentfile
,
path
)
<
0
?
-
1
:
i
;
return
copy_file
(
commentfile
,
path
)
<
0
?
-
1
:
i
;
}
}
...
@@ -4100,6 +4217,7 @@ static char *get_snapcomment_path(char* snappath, char *name)
...
@@ -4100,6 +4217,7 @@ static char *get_snapcomment_path(char* snappath, char *name)
s
=
NULL
;
s
=
NULL
;
}
}
}
}
return
s
;
return
s
;
}
}
...
@@ -4112,9 +4230,11 @@ static char *get_timestamp(char* snappath, char *name)
...
@@ -4112,9 +4230,11 @@ static char *get_timestamp(char* snappath, char *name)
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"%s/%s/ts"
,
snappath
,
name
);
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"%s/%s/ts"
,
snappath
,
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
NULL
;
return
NULL
;
fin
=
fopen
(
path
,
"r"
);
fin
=
fopen
(
path
,
"r"
);
if
(
!
fin
)
if
(
!
fin
)
return
NULL
;
return
NULL
;
(
void
)
fseek
(
fin
,
0
,
SEEK_END
);
(
void
)
fseek
(
fin
,
0
,
SEEK_END
);
len
=
ftell
(
fin
);
len
=
ftell
(
fin
);
(
void
)
fseek
(
fin
,
0
,
SEEK_SET
);
(
void
)
fseek
(
fin
,
0
,
SEEK_SET
);
...
@@ -4129,6 +4249,7 @@ static char *get_timestamp(char* snappath, char *name)
...
@@ -4129,6 +4249,7 @@ static char *get_timestamp(char* snappath, char *name)
}
}
}
}
}
}
fclose
(
fin
);
fclose
(
fin
);
return
s
;
return
s
;
}
}
...
@@ -4148,9 +4269,10 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
...
@@ -4148,9 +4269,10 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR
(
"path name too long"
);
ERROR
(
"path name too long"
);
return
-
1
;
return
-
1
;
}
}
dir
=
opendir
(
snappath
);
dir
=
opendir
(
snappath
);
if
(
!
dir
)
{
if
(
!
dir
)
{
INFO
(
"
f
ailed to open %s - assuming no snapshots"
,
snappath
);
INFO
(
"
F
ailed to open %s - assuming no snapshots"
,
snappath
);
return
0
;
return
0
;
}
}
...
@@ -4166,30 +4288,35 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
...
@@ -4166,30 +4288,35 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR
(
"pathname too long"
);
ERROR
(
"pathname too long"
);
goto
out_free
;
goto
out_free
;
}
}
if
(
!
file_exists
(
path2
))
if
(
!
file_exists
(
path2
))
continue
;
continue
;
nsnaps
=
realloc
(
snaps
,
(
count
+
1
)
*
sizeof
(
*
snaps
));
nsnaps
=
realloc
(
snaps
,
(
count
+
1
)
*
sizeof
(
*
snaps
));
if
(
!
nsnaps
)
{
if
(
!
nsnaps
)
{
SYSERROR
(
"Out of memory"
);
SYSERROR
(
"Out of memory"
);
goto
out_free
;
goto
out_free
;
}
}
snaps
=
nsnaps
;
snaps
=
nsnaps
;
snaps
[
count
].
free
=
lxcsnap_free
;
snaps
[
count
].
free
=
lxcsnap_free
;
snaps
[
count
].
name
=
strdup
(
direntp
->
d_name
);
snaps
[
count
].
name
=
strdup
(
direntp
->
d_name
);
if
(
!
snaps
[
count
].
name
)
if
(
!
snaps
[
count
].
name
)
goto
out_free
;
goto
out_free
;
snaps
[
count
].
lxcpath
=
strdup
(
snappath
);
snaps
[
count
].
lxcpath
=
strdup
(
snappath
);
if
(
!
snaps
[
count
].
lxcpath
)
{
if
(
!
snaps
[
count
].
lxcpath
)
{
free
(
snaps
[
count
].
name
);
free
(
snaps
[
count
].
name
);
goto
out_free
;
goto
out_free
;
}
}
snaps
[
count
].
comment_pathname
=
get_snapcomment_path
(
snappath
,
direntp
->
d_name
);
snaps
[
count
].
comment_pathname
=
get_snapcomment_path
(
snappath
,
direntp
->
d_name
);
snaps
[
count
].
timestamp
=
get_timestamp
(
snappath
,
direntp
->
d_name
);
snaps
[
count
].
timestamp
=
get_timestamp
(
snappath
,
direntp
->
d_name
);
count
++
;
count
++
;
}
}
if
(
closedir
(
dir
))
if
(
closedir
(
dir
))
WARN
(
"
f
ailed to close directory"
);
WARN
(
"
F
ailed to close directory"
);
*
ret_snaps
=
snaps
;
*
ret_snaps
=
snaps
;
return
count
;
return
count
;
...
@@ -4197,12 +4324,16 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
...
@@ -4197,12 +4324,16 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
out_free
:
out_free
:
if
(
snaps
)
{
if
(
snaps
)
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
for
(
i
=
0
;
i
<
count
;
i
++
)
lxcsnap_free
(
&
snaps
[
i
]);
lxcsnap_free
(
&
snaps
[
i
]);
free
(
snaps
);
free
(
snaps
);
}
}
if
(
closedir
(
dir
))
if
(
closedir
(
dir
))
WARN
(
"failed to close directory"
);
WARN
(
"Failed to close directory"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -4250,8 +4381,10 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
...
@@ -4250,8 +4381,10 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
snap
=
lxc_container_new
(
snapname
,
clonelxcpath
);
snap
=
lxc_container_new
(
snapname
,
clonelxcpath
);
if
(
!
snap
||
!
lxcapi_is_defined
(
snap
))
{
if
(
!
snap
||
!
lxcapi_is_defined
(
snap
))
{
ERROR
(
"Could not open snapshot %s"
,
snapname
);
ERROR
(
"Could not open snapshot %s"
,
snapname
);
if
(
snap
)
if
(
snap
)
lxc_container_put
(
snap
);
lxc_container_put
(
snap
);
storage_put
(
bdev
);
storage_put
(
bdev
);
return
false
;
return
false
;
}
}
...
@@ -4270,11 +4403,13 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
...
@@ -4270,11 +4403,13 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
if
(
!
strcmp
(
bdev
->
type
,
"overlay"
)
||
!
strcmp
(
bdev
->
type
,
"overlayfs"
))
if
(
!
strcmp
(
bdev
->
type
,
"overlay"
)
||
!
strcmp
(
bdev
->
type
,
"overlayfs"
))
flags
|=
LXC_STORAGE_INTERNAL_OVERLAY_RESTORE
;
flags
|=
LXC_STORAGE_INTERNAL_OVERLAY_RESTORE
;
rest
=
lxcapi_clone
(
snap
,
newname
,
c
->
config_path
,
flags
,
bdev
->
type
,
rest
=
lxcapi_clone
(
snap
,
newname
,
c
->
config_path
,
flags
,
bdev
->
type
,
NULL
,
0
,
NULL
);
NULL
,
0
,
NULL
);
storage_put
(
bdev
);
storage_put
(
bdev
);
if
(
rest
&&
lxcapi_is_defined
(
rest
))
if
(
rest
&&
lxcapi_is_defined
(
rest
))
b
=
true
;
b
=
true
;
if
(
rest
)
if
(
rest
)
lxc_container_put
(
rest
);
lxc_container_put
(
rest
);
...
@@ -4299,11 +4434,13 @@ static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath)
...
@@ -4299,11 +4434,13 @@ static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath)
ERROR
(
"Could not destroy snapshot %s"
,
snapname
);
ERROR
(
"Could not destroy snapshot %s"
,
snapname
);
goto
err
;
goto
err
;
}
}
bret
=
true
;
bret
=
true
;
err
:
err
:
if
(
snap
)
if
(
snap
)
lxc_container_put
(
snap
);
lxc_container_put
(
snap
);
return
bret
;
return
bret
;
}
}
...
@@ -4318,11 +4455,14 @@ static bool remove_all_snapshots(const char *path)
...
@@ -4318,11 +4455,14 @@ static bool remove_all_snapshots(const char *path)
SYSERROR
(
"opendir on snapshot path %s"
,
path
);
SYSERROR
(
"opendir on snapshot path %s"
,
path
);
return
false
;
return
false
;
}
}
while
((
direntp
=
readdir
(
dir
)))
{
while
((
direntp
=
readdir
(
dir
)))
{
if
(
!
strcmp
(
direntp
->
d_name
,
"."
))
if
(
!
strcmp
(
direntp
->
d_name
,
"."
))
continue
;
continue
;
if
(
!
strcmp
(
direntp
->
d_name
,
".."
))
if
(
!
strcmp
(
direntp
->
d_name
,
".."
))
continue
;
continue
;
if
(
!
do_snapshot_destroy
(
direntp
->
d_name
,
path
))
{
if
(
!
do_snapshot_destroy
(
direntp
->
d_name
,
path
))
{
bret
=
false
;
bret
=
false
;
continue
;
continue
;
...
@@ -4507,6 +4647,7 @@ static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_p
...
@@ -4507,6 +4647,7 @@ static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_p
ERROR
(
LXC_UNPRIV_EOPNOTSUPP
,
__FUNCTION__
);
ERROR
(
LXC_UNPRIV_EOPNOTSUPP
,
__FUNCTION__
);
return
false
;
return
false
;
}
}
return
add_remove_device_node
(
c
,
src_path
,
dest_path
,
true
);
return
add_remove_device_node
(
c
,
src_path
,
dest_path
,
true
);
}
}
...
@@ -4518,6 +4659,7 @@ static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *sr
...
@@ -4518,6 +4659,7 @@ static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *sr
ERROR
(
LXC_UNPRIV_EOPNOTSUPP
,
__FUNCTION__
);
ERROR
(
LXC_UNPRIV_EOPNOTSUPP
,
__FUNCTION__
);
return
false
;
return
false
;
}
}
return
add_remove_device_node
(
c
,
src_path
,
dest_path
,
false
);
return
add_remove_device_node
(
c
,
src_path
,
dest_path
,
false
);
}
}
...
@@ -4621,6 +4763,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
...
@@ -4621,6 +4763,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
ERROR
(
"Network device
\"
%s
\"
not found"
,
ifname
);
ERROR
(
"Network device
\"
%s
\"
not found"
,
ifname
);
else
else
ERROR
(
"Failed to remove network device
\"
%s
\"
"
,
ifname
);
ERROR
(
"Failed to remove network device
\"
%s
\"
"
,
ifname
);
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
...
@@ -4654,12 +4797,11 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
...
@@ -4654,12 +4797,11 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
addr
=
(
void
*
)
opts
+
sizeof
(
*
opts
);
addr
=
(
void
*
)
opts
+
sizeof
(
*
opts
);
end
=
(
void
*
)
opts
+
size
;
end
=
(
void
*
)
opts
+
size
;
for
(;
addr
<
end
;
addr
++
)
{
if
(
*
addr
)
{
for
(;
addr
<
end
;
addr
++
)
if
(
*
addr
)
return
-
E2BIG
;
return
-
E2BIG
;
}
}
}
}
/* If the caller has a smaller struct, let's zero out the end for them
/* If the caller has a smaller struct, let's zero out the end for them
* so we don't accidentally use bits of it that they didn't know about
* so we don't accidentally use bits of it that they didn't know about
...
@@ -4680,6 +4822,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
...
@@ -4680,6 +4822,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR
(
"container is not running"
);
ERROR
(
"container is not running"
);
goto
on_error
;
goto
on_error
;
}
}
ret
=
!
__criu_pre_dump
(
c
,
valid_opts
);
ret
=
!
__criu_pre_dump
(
c
,
valid_opts
);
break
;
break
;
case
MIGRATE_DUMP
:
case
MIGRATE_DUMP
:
...
@@ -4687,6 +4830,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
...
@@ -4687,6 +4830,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR
(
"container is not running"
);
ERROR
(
"container is not running"
);
goto
on_error
;
goto
on_error
;
}
}
ret
=
!
__criu_dump
(
c
,
valid_opts
);
ret
=
!
__criu_dump
(
c
,
valid_opts
);
break
;
break
;
case
MIGRATE_RESTORE
:
case
MIGRATE_RESTORE
:
...
@@ -4694,6 +4838,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
...
@@ -4694,6 +4838,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR
(
"container is already running"
);
ERROR
(
"container is already running"
);
goto
on_error
;
goto
on_error
;
}
}
ret
=
!
__criu_restore
(
c
,
valid_opts
);
ret
=
!
__criu_restore
(
c
,
valid_opts
);
break
;
break
;
case
MIGRATE_FEATURE_CHECK
:
case
MIGRATE_FEATURE_CHECK
:
...
@@ -4772,6 +4917,7 @@ static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t
...
@@ -4772,6 +4917,7 @@ static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t
ret
=
do_lxcapi_attach_run_wait
(
c
,
options
,
program
,
(
const
char
*
const
*
)
argv
);
ret
=
do_lxcapi_attach_run_wait
(
c
,
options
,
program
,
(
const
char
*
const
*
)
argv
);
free
((
void
*
)
argv
);
free
((
void
*
)
argv
);
out
:
out
:
current_config
=
NULL
;
current_config
=
NULL
;
return
ret
;
return
ret
;
...
@@ -4796,7 +4942,6 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
...
@@ -4796,7 +4942,6 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c
->
config_path
=
strdup
(
configpath
);
c
->
config_path
=
strdup
(
configpath
);
else
else
c
->
config_path
=
strdup
(
lxc_global_config_value
(
"lxc.lxcpath"
));
c
->
config_path
=
strdup
(
lxc_global_config_value
(
"lxc.lxcpath"
));
if
(
!
c
->
config_path
)
{
if
(
!
c
->
config_path
)
{
fprintf
(
stderr
,
"Failed to allocate memory for %s
\n
"
,
name
);
fprintf
(
stderr
,
"Failed to allocate memory for %s
\n
"
,
name
);
goto
err
;
goto
err
;
...
@@ -4840,6 +4985,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
...
@@ -4840,6 +4985,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
container_destroy
(
c
,
NULL
);
container_destroy
(
c
,
NULL
);
lxcapi_clear_config
(
c
);
lxcapi_clear_config
(
c
);
}
}
c
->
daemonize
=
true
;
c
->
daemonize
=
true
;
c
->
pidfile
=
NULL
;
c
->
pidfile
=
NULL
;
...
@@ -4914,6 +5060,7 @@ int lxc_get_wait_states(const char **states)
...
@@ -4914,6 +5060,7 @@ int lxc_get_wait_states(const char **states)
if
(
states
)
if
(
states
)
for
(
i
=
0
;
i
<
MAX_STATE
;
i
++
)
for
(
i
=
0
;
i
<
MAX_STATE
;
i
++
)
states
[
i
]
=
lxc_state2str
(
i
);
states
[
i
]
=
lxc_state2str
(
i
);
return
MAX_STATE
;
return
MAX_STATE
;
}
}
...
@@ -4939,6 +5086,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
...
@@ -4939,6 +5086,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if
(
cret
)
if
(
cret
)
*
cret
=
NULL
;
*
cret
=
NULL
;
if
(
names
)
if
(
names
)
*
names
=
NULL
;
*
names
=
NULL
;
...
@@ -4950,10 +5098,10 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
...
@@ -4950,10 +5098,10 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if
(
!
config_file_exists
(
lxcpath
,
direntp
->
d_name
))
if
(
!
config_file_exists
(
lxcpath
,
direntp
->
d_name
))
continue
;
continue
;
if
(
names
)
{
if
(
names
)
if
(
!
add_to_array
(
names
,
direntp
->
d_name
,
cfound
))
if
(
!
add_to_array
(
names
,
direntp
->
d_name
,
cfound
))
goto
free_bad
;
goto
free_bad
;
}
cfound
++
;
cfound
++
;
if
(
!
cret
)
{
if
(
!
cret
)
{
...
@@ -4965,17 +5113,22 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
...
@@ -4965,17 +5113,22 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if
(
!
c
)
{
if
(
!
c
)
{
INFO
(
"Container %s:%s has a config but could not be loaded"
,
INFO
(
"Container %s:%s has a config but could not be loaded"
,
lxcpath
,
direntp
->
d_name
);
lxcpath
,
direntp
->
d_name
);
if
(
names
)
if
(
names
)
if
(
!
remove_from_array
(
names
,
direntp
->
d_name
,
cfound
--
))
if
(
!
remove_from_array
(
names
,
direntp
->
d_name
,
cfound
--
))
goto
free_bad
;
goto
free_bad
;
continue
;
continue
;
}
}
if
(
!
do_lxcapi_is_defined
(
c
))
{
if
(
!
do_lxcapi_is_defined
(
c
))
{
INFO
(
"Container %s:%s has a config but is not defined"
,
INFO
(
"Container %s:%s has a config but is not defined"
,
lxcpath
,
direntp
->
d_name
);
lxcpath
,
direntp
->
d_name
);
if
(
names
)
if
(
names
)
if
(
!
remove_from_array
(
names
,
direntp
->
d_name
,
cfound
--
))
if
(
!
remove_from_array
(
names
,
direntp
->
d_name
,
cfound
--
))
goto
free_bad
;
goto
free_bad
;
lxc_container_put
(
c
);
lxc_container_put
(
c
);
continue
;
continue
;
}
}
...
@@ -4984,6 +5137,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
...
@@ -4984,6 +5137,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
lxc_container_put
(
c
);
lxc_container_put
(
c
);
goto
free_bad
;
goto
free_bad
;
}
}
nfound
++
;
nfound
++
;
}
}
...
@@ -4996,11 +5150,13 @@ free_bad:
...
@@ -4996,11 +5150,13 @@ free_bad:
free
((
*
names
)[
i
]);
free
((
*
names
)[
i
]);
free
(
*
names
);
free
(
*
names
);
}
}
if
(
cret
&&
*
cret
)
{
if
(
cret
&&
*
cret
)
{
for
(
i
=
0
;
i
<
nfound
;
i
++
)
for
(
i
=
0
;
i
<
nfound
;
i
++
)
lxc_container_put
((
*
cret
)[
i
]);
lxc_container_put
((
*
cret
)[
i
]);
free
(
*
cret
);
free
(
*
cret
);
}
}
closedir
(
dir
);
closedir
(
dir
);
return
-
1
;
return
-
1
;
}
}
...
@@ -5022,6 +5178,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
...
@@ -5022,6 +5178,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
if
(
cret
)
if
(
cret
)
*
cret
=
NULL
;
*
cret
=
NULL
;
if
(
nret
)
if
(
nret
)
*
nret
=
NULL
;
*
nret
=
NULL
;
...
@@ -5030,16 +5187,17 @@ int list_active_containers(const char *lxcpath, char ***nret,
...
@@ -5030,16 +5187,17 @@ int list_active_containers(const char *lxcpath, char ***nret,
return
-
1
;
return
-
1
;
while
(
getline
(
&
line
,
&
len
,
f
)
!=
-
1
)
{
while
(
getline
(
&
line
,
&
len
,
f
)
!=
-
1
)
{
char
*
p
=
strrchr
(
line
,
' '
),
*
p2
;
char
*
p
=
strrchr
(
line
,
' '
),
*
p2
;
if
(
!
p
)
if
(
!
p
)
continue
;
continue
;
p
++
;
p
++
;
if
(
*
p
!=
0x40
)
if
(
*
p
!=
0x40
)
continue
;
continue
;
p
++
;
p
++
;
is_hashed
=
false
;
is_hashed
=
false
;
if
(
strncmp
(
p
,
lxcpath
,
lxcpath_len
)
==
0
)
{
if
(
strncmp
(
p
,
lxcpath
,
lxcpath_len
)
==
0
)
{
p
+=
lxcpath_len
;
p
+=
lxcpath_len
;
}
else
if
(
strncmp
(
p
,
"lxc/"
,
4
)
==
0
)
{
}
else
if
(
strncmp
(
p
,
"lxc/"
,
4
)
==
0
)
{
...
@@ -5062,11 +5220,13 @@ int list_active_containers(const char *lxcpath, char ***nret,
...
@@ -5062,11 +5220,13 @@ int list_active_containers(const char *lxcpath, char ***nret,
char
*
recvpath
=
lxc_cmd_get_lxcpath
(
p
);
char
*
recvpath
=
lxc_cmd_get_lxcpath
(
p
);
if
(
!
recvpath
)
if
(
!
recvpath
)
continue
;
continue
;
if
(
strncmp
(
lxcpath
,
recvpath
,
lxcpath_len
)
!=
0
)
{
if
(
strncmp
(
lxcpath
,
recvpath
,
lxcpath_len
)
!=
0
)
{
free
(
recvpath
);
free
(
recvpath
);
continue
;
continue
;
}
}
free
(
recvpath
);
free
(
recvpath
);
p
=
lxc_cmd_get_name
(
p
);
p
=
lxc_cmd_get_name
(
p
);
if
(
!
p
)
if
(
!
p
)
continue
;
continue
;
...
@@ -5096,9 +5256,11 @@ int list_active_containers(const char *lxcpath, char ***nret,
...
@@ -5096,9 +5256,11 @@ int list_active_containers(const char *lxcpath, char ***nret,
if
(
!
c
)
{
if
(
!
c
)
{
INFO
(
"Container %s:%s is running but could not be loaded"
,
INFO
(
"Container %s:%s is running but could not be loaded"
,
lxcpath
,
p
);
lxcpath
,
p
);
remove_from_array
(
&
ct_name
,
p
,
ct_name_cnt
--
);
remove_from_array
(
&
ct_name
,
p
,
ct_name_cnt
--
);
if
(
is_hashed
)
if
(
is_hashed
)
free
(
p
);
free
(
p
);
continue
;
continue
;
}
}
...
@@ -5115,6 +5277,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
...
@@ -5115,6 +5277,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
lxc_container_put
(
c
);
lxc_container_put
(
c
);
goto
free_cret_list
;
goto
free_cret_list
;
}
}
cret_cnt
++
;
cret_cnt
++
;
}
}
...
@@ -5129,6 +5292,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
...
@@ -5129,6 +5292,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
*
nret
=
ct_name
;
*
nret
=
ct_name
;
else
else
goto
free_ct_name
;
goto
free_ct_name
;
goto
out
;
goto
out
;
free_cret_list
:
free_cret_list
:
...
@@ -5147,7 +5311,6 @@ free_ct_name:
...
@@ -5147,7 +5311,6 @@ free_ct_name:
out
:
out
:
free
(
line
);
free
(
line
);
fclose
(
f
);
fclose
(
f
);
return
ret
;
return
ret
;
}
}
...
@@ -5176,11 +5339,14 @@ int list_all_containers(const char *lxcpath, char ***nret,
...
@@ -5176,11 +5339,14 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret
=
-
1
;
ret
=
-
1
;
goto
free_active_name
;
goto
free_active_name
;
}
}
ct_cnt
++
;
ct_cnt
++
;
}
}
free
(
active_name
[
i
]);
free
(
active_name
[
i
]);
active_name
[
i
]
=
NULL
;
active_name
[
i
]
=
NULL
;
}
}
free
(
active_name
);
free
(
active_name
);
active_name
=
NULL
;
active_name
=
NULL
;
active_cnt
=
0
;
active_cnt
=
0
;
...
@@ -5200,18 +5366,20 @@ int list_all_containers(const char *lxcpath, char ***nret,
...
@@ -5200,18 +5366,20 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret
=
-
1
;
ret
=
-
1
;
goto
free_ct_list
;
goto
free_ct_list
;
}
}
ct_list_cnt
++
;
ct_list_cnt
++
;
}
}
if
(
cret
)
if
(
cret
)
*
cret
=
ct_list
;
*
cret
=
ct_list
;
if
(
nret
)
if
(
nret
)
{
*
nret
=
ct_name
;
*
nret
=
ct_name
;
else
{
}
else
{
ret
=
ct_cnt
;
ret
=
ct_cnt
;
goto
free_ct_name
;
goto
free_ct_name
;
}
}
return
ct_cnt
;
return
ct_cnt
;
free_ct_list
:
free_ct_list
:
...
...
src/lxc/start.c
View file @
010a85d1
...
@@ -490,11 +490,17 @@ static int lxc_serve_state_socket_pair(const char *name,
...
@@ -490,11 +490,17 @@ static int lxc_serve_state_socket_pair(const char *name,
again:
again:
ret
=
lxc_abstract_unix_send_credential
(
handler
->
state_socket_pair
[
1
],
ret
=
lxc_abstract_unix_send_credential
(
handler
->
state_socket_pair
[
1
],
&
(
int
){
state
},
sizeof
(
int
));
&
(
int
){
state
},
sizeof
(
int
));
if
(
ret
!=
sizeof
(
int
))
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to send state to %d"
,
handler
->
state_socket_pair
[
1
]);
if
(
errno
==
EINTR
)
if
(
errno
==
EINTR
)
goto
again
;
goto
again
;
SYSERROR
(
"Failed to send state to %d"
,
handler
->
state_socket_pair
[
1
]);
return
-
1
;
}
if
(
ret
!=
sizeof
(
int
))
{
ERROR
(
"Message too long : %d"
,
handler
->
state_socket_pair
[
1
]);
return
-
1
;
return
-
1
;
}
}
...
@@ -649,7 +655,7 @@ void lxc_free_handler(struct lxc_handler *handler)
...
@@ -649,7 +655,7 @@ void lxc_free_handler(struct lxc_handler *handler)
if
(
handler
->
conf
&&
handler
->
conf
->
reboot
==
REBOOT_NONE
)
if
(
handler
->
conf
&&
handler
->
conf
->
reboot
==
REBOOT_NONE
)
if
(
handler
->
conf
->
maincmd_fd
>=
0
)
if
(
handler
->
conf
->
maincmd_fd
>=
0
)
close
(
handler
->
conf
->
maincmd_fd
);
lxc_abstract_unix_
close
(
handler
->
conf
->
maincmd_fd
);
if
(
handler
->
state_socket_pair
[
0
]
>=
0
)
if
(
handler
->
state_socket_pair
[
0
]
>=
0
)
close
(
handler
->
state_socket_pair
[
0
]);
close
(
handler
->
state_socket_pair
[
0
]);
...
@@ -671,6 +677,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
...
@@ -671,6 +677,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
handler
=
malloc
(
sizeof
(
*
handler
));
handler
=
malloc
(
sizeof
(
*
handler
));
if
(
!
handler
)
if
(
!
handler
)
return
NULL
;
return
NULL
;
memset
(
handler
,
0
,
sizeof
(
*
handler
));
memset
(
handler
,
0
,
sizeof
(
*
handler
));
/* Note that am_guest_unpriv() checks the effective uid. We
/* Note that am_guest_unpriv() checks the effective uid. We
...
@@ -704,6 +711,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
...
@@ -704,6 +711,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
ERROR
(
"Failed to create anonymous pair of unix sockets"
);
ERROR
(
"Failed to create anonymous pair of unix sockets"
);
goto
on_error
;
goto
on_error
;
}
}
TRACE
(
"Created anonymous pair {%d,%d} of unix sockets"
,
TRACE
(
"Created anonymous pair {%d,%d} of unix sockets"
,
handler
->
state_socket_pair
[
0
],
handler
->
state_socket_pair
[
0
],
handler
->
state_socket_pair
[
1
]);
handler
->
state_socket_pair
[
1
]);
...
@@ -716,6 +724,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
...
@@ -716,6 +724,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
goto
on_error
;
goto
on_error
;
}
}
}
}
TRACE
(
"Unix domain socket %d for command server is ready"
,
TRACE
(
"Unix domain socket %d for command server is ready"
,
handler
->
conf
->
maincmd_fd
);
handler
->
conf
->
maincmd_fd
);
...
@@ -866,7 +875,7 @@ out_delete_tty:
...
@@ -866,7 +875,7 @@ out_delete_tty:
out_aborting:
out_aborting:
(
void
)
lxc_set_state
(
name
,
handler
,
ABORTING
);
(
void
)
lxc_set_state
(
name
,
handler
,
ABORTING
);
out_close_maincmd_fd:
out_close_maincmd_fd:
close
(
conf
->
maincmd_fd
);
lxc_abstract_unix_
close
(
conf
->
maincmd_fd
);
conf
->
maincmd_fd
=
-
1
;
conf
->
maincmd_fd
=
-
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -953,7 +962,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
...
@@ -953,7 +962,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
* the command socket causing a new process to get ECONNREFUSED
* the command socket causing a new process to get ECONNREFUSED
* because we haven't yet closed the command socket.
* because we haven't yet closed the command socket.
*/
*/
close
(
handler
->
conf
->
maincmd_fd
);
lxc_abstract_unix_
close
(
handler
->
conf
->
maincmd_fd
);
handler
->
conf
->
maincmd_fd
=
-
1
;
handler
->
conf
->
maincmd_fd
=
-
1
;
TRACE
(
"Closed command socket"
);
TRACE
(
"Closed command socket"
);
...
...
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