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
4be37478
Commit
4be37478
authored
Nov 26, 2016
by
Christian Brauner
Committed by
Stéphane Graber
Nov 30, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
monitor: non-functional changes
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
19b5201a
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
80 additions
and
59 deletions
+80
-59
monitor.c
src/lxc/monitor.c
+80
-59
No files found.
src/lxc/monitor.c
View file @
4be37478
...
@@ -22,30 +22,31 @@
...
@@ -22,30 +22,31 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
*/
#include <stdio.h>
#include <errno.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <fcntl.h>
#include <fcntl.h>
#include <inttypes.h>
#include <inttypes.h>
#include <poll.h>
#include <stddef.h>
#include <stdint.h>
#include <stdint.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <net/if.h>
#include <poll.h>
#include "
error
.h"
#include "
config
.h"
#include "af_unix.h"
#include "af_unix.h"
#include "error.h"
#include "log.h"
#include "log.h"
#include "lxclock.h"
#include "lxclock.h"
#include "state.h"
#include "monitor.h"
#include "monitor.h"
#include "state.h"
#include "utils.h"
#include "utils.h"
lxc_log_define
(
lxc_monitor
,
lxc
);
lxc_log_define
(
lxc_monitor
,
lxc
);
...
@@ -63,21 +64,21 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
...
@@ -63,21 +64,21 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
if
(
do_mkdirp
)
{
if
(
do_mkdirp
)
{
ret
=
snprintf
(
fifo_path
,
fifo_path_sz
,
"%s/lxc/%s"
,
rundir
,
lxcpath
);
ret
=
snprintf
(
fifo_path
,
fifo_path_sz
,
"%s/lxc/%s"
,
rundir
,
lxcpath
);
if
(
ret
<
0
||
ret
>=
fifo_path_sz
)
{
if
(
ret
<
0
||
(
size_t
)
ret
>=
fifo_path_sz
)
{
ERROR
(
"rundir/lxcpath (%s/%s) too long for monitor fifo"
,
rundir
,
lxcpath
);
ERROR
(
"rundir/lxcpath (%s/%s) too long for monitor fifo
.
"
,
rundir
,
lxcpath
);
free
(
rundir
);
free
(
rundir
);
return
-
1
;
return
-
1
;
}
}
ret
=
mkdir_p
(
fifo_path
,
0755
);
ret
=
mkdir_p
(
fifo_path
,
0755
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"
unable to create monitor fifo dir %s
"
,
fifo_path
);
ERROR
(
"
Unable to create monitor fifo directory %s.
"
,
fifo_path
);
free
(
rundir
);
free
(
rundir
);
return
ret
;
return
ret
;
}
}
}
}
ret
=
snprintf
(
fifo_path
,
fifo_path_sz
,
"%s/lxc/%s/monitor-fifo"
,
rundir
,
lxcpath
);
ret
=
snprintf
(
fifo_path
,
fifo_path_sz
,
"%s/lxc/%s/monitor-fifo"
,
rundir
,
lxcpath
);
if
(
ret
<
0
||
ret
>=
fifo_path_sz
)
{
if
(
ret
<
0
||
(
size_t
)
ret
>=
fifo_path_sz
)
{
ERROR
(
"rundir/lxcpath (%s/%s) too long for monitor fifo"
,
rundir
,
lxcpath
);
ERROR
(
"rundir/lxcpath (%s/%s) too long for monitor fifo
.
"
,
rundir
,
lxcpath
);
free
(
rundir
);
free
(
rundir
);
return
-
1
;
return
-
1
;
}
}
...
@@ -96,14 +97,18 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
...
@@ -96,14 +97,18 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
if
(
ret
<
0
)
if
(
ret
<
0
)
return
;
return
;
/*
open the fifo nonblock in case the monitor is dead, we don't want
/*
Open the fifo nonblock in case the monitor is dead, we don't want the
*
the
open to wait for a reader since it may never come.
* open to wait for a reader since it may never come.
*/
*/
fd
=
open
(
fifo_path
,
O_WRONLY
|
O_NONBLOCK
);
fd
=
open
(
fifo_path
,
O_WRONLY
|
O_NONBLOCK
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
/*
it is normal for this open to fail ENXIO when there is no
/*
It is normal for this open() to fail with ENXIO when there is
*
monitor running, so we don't log it
*
no monitor running, so we don't log it.
*/
*/
if
(
errno
==
ENXIO
)
return
;
WARN
(
"Failed to open fifo to send message: %s."
,
strerror
(
errno
));
return
;
return
;
}
}
...
@@ -115,34 +120,33 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
...
@@ -115,34 +120,33 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
ret
=
write
(
fd
,
msg
,
sizeof
(
*
msg
));
ret
=
write
(
fd
,
msg
,
sizeof
(
*
msg
));
if
(
ret
!=
sizeof
(
*
msg
))
{
if
(
ret
!=
sizeof
(
*
msg
))
{
close
(
fd
);
close
(
fd
);
SYSERROR
(
"
failed to write monitor fifo %s
"
,
fifo_path
);
SYSERROR
(
"
Failed to write to monitor fifo
\"
%s
\"
.
"
,
fifo_path
);
return
;
return
;
}
}
close
(
fd
);
close
(
fd
);
}
}
void
lxc_monitor_send_state
(
const
char
*
name
,
lxc_state_t
state
,
const
char
*
lxcpath
)
void
lxc_monitor_send_state
(
const
char
*
name
,
lxc_state_t
state
,
const
char
*
lxcpath
)
{
{
struct
lxc_msg
msg
=
{
.
type
=
lxc_msg_state
,
struct
lxc_msg
msg
=
{.
type
=
lxc_msg_state
,
.
value
=
state
};
.
value
=
state
};
strncpy
(
msg
.
name
,
name
,
sizeof
(
msg
.
name
));
strncpy
(
msg
.
name
,
name
,
sizeof
(
msg
.
name
));
msg
.
name
[
sizeof
(
msg
.
name
)
-
1
]
=
0
;
msg
.
name
[
sizeof
(
msg
.
name
)
-
1
]
=
0
;
lxc_monitor_fifo_send
(
&
msg
,
lxcpath
);
lxc_monitor_fifo_send
(
&
msg
,
lxcpath
);
}
}
void
lxc_monitor_send_exit_code
(
const
char
*
name
,
int
exit_code
,
const
char
*
lxcpath
)
void
lxc_monitor_send_exit_code
(
const
char
*
name
,
int
exit_code
,
const
char
*
lxcpath
)
{
{
struct
lxc_msg
msg
=
{
.
type
=
lxc_msg_exit_code
,
struct
lxc_msg
msg
=
{.
type
=
lxc_msg_exit_code
,
.
value
=
exit_code
};
.
value
=
exit_code
};
strncpy
(
msg
.
name
,
name
,
sizeof
(
msg
.
name
));
strncpy
(
msg
.
name
,
name
,
sizeof
(
msg
.
name
));
msg
.
name
[
sizeof
(
msg
.
name
)
-
1
]
=
0
;
msg
.
name
[
sizeof
(
msg
.
name
)
-
1
]
=
0
;
lxc_monitor_fifo_send
(
&
msg
,
lxcpath
);
lxc_monitor_fifo_send
(
&
msg
,
lxcpath
);
}
}
/* routines used by monitor subscribers (lxc-monitor) */
/* routines used by monitor subscribers (lxc-monitor) */
int
lxc_monitor_close
(
int
fd
)
int
lxc_monitor_close
(
int
fd
)
{
{
...
@@ -152,20 +156,22 @@ int lxc_monitor_close(int fd)
...
@@ -152,20 +156,22 @@ int lxc_monitor_close(int fd)
int
lxc_monitor_sock_name
(
const
char
*
lxcpath
,
struct
sockaddr_un
*
addr
)
{
int
lxc_monitor_sock_name
(
const
char
*
lxcpath
,
struct
sockaddr_un
*
addr
)
{
size_t
len
;
size_t
len
;
int
ret
;
int
ret
;
char
*
sockname
=
&
addr
->
sun_path
[
1
]
;
char
*
sockname
;
char
*
path
;
char
*
path
;
uint64_t
hash
;
uint64_t
hash
;
/* addr.sun_path is only 108 bytes, so we hash the full name and
/* addr.sun_path is only 108 bytes, so we hash the full name and
* then append as much of the name as we can fit.
* then append as much of the name as we can fit.
*/
*/
sockname
=
&
addr
->
sun_path
[
1
];
memset
(
addr
,
0
,
sizeof
(
*
addr
));
memset
(
addr
,
0
,
sizeof
(
*
addr
));
addr
->
sun_family
=
AF_UNIX
;
addr
->
sun_family
=
AF_UNIX
;
len
=
strlen
(
lxcpath
)
+
18
;
len
=
strlen
(
lxcpath
)
+
18
;
path
=
alloca
(
len
);
path
=
alloca
(
len
);
ret
=
snprintf
(
path
,
len
,
"lxc/%s/monitor-sock"
,
lxcpath
);
ret
=
snprintf
(
path
,
len
,
"lxc/%s/monitor-sock"
,
lxcpath
);
if
(
ret
<
0
||
ret
>=
len
)
{
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
{
ERROR
(
"
memory error creating monitor path
"
);
ERROR
(
"
Failed to create path for monitor.
"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -174,24 +180,27 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
...
@@ -174,24 +180,27 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
ret
=
snprintf
(
sockname
,
len
,
"lxc/%016"
PRIx64
"/%s"
,
hash
,
lxcpath
);
ret
=
snprintf
(
sockname
,
len
,
"lxc/%016"
PRIx64
"/%s"
,
hash
,
lxcpath
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
sockname
[
sizeof
(
addr
->
sun_path
)
-
3
]
=
'\0'
;
sockname
[
sizeof
(
addr
->
sun_path
)
-
3
]
=
'\0'
;
INFO
(
"using monitor sock name %s"
,
sockname
);
INFO
(
"Using monitor socket name
\"
%s
\"
."
,
sockname
);
return
0
;
return
0
;
}
}
int
lxc_monitor_open
(
const
char
*
lxcpath
)
int
lxc_monitor_open
(
const
char
*
lxcpath
)
{
{
struct
sockaddr_un
addr
;
struct
sockaddr_un
addr
;
int
fd
,
ret
=
0
;
int
fd
;
int
retry
,
backoff_ms
[]
=
{
10
,
50
,
100
}
;
size_t
retry
;
size_t
len
;
size_t
len
;
int
ret
=
0
,
backoff_ms
[]
=
{
10
,
50
,
100
};
if
(
lxc_monitor_sock_name
(
lxcpath
,
&
addr
)
<
0
)
if
(
lxc_monitor_sock_name
(
lxcpath
,
&
addr
)
<
0
)
return
-
1
;
return
-
1
;
fd
=
socket
(
PF_UNIX
,
SOCK_STREAM
,
0
);
fd
=
socket
(
PF_UNIX
,
SOCK_STREAM
,
0
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
ERROR
(
"
socket : %s
"
,
strerror
(
errno
));
ERROR
(
"
Failed to create socket: %s.
"
,
strerror
(
errno
));
return
-
1
;
return
-
1
;
}
}
...
@@ -199,23 +208,25 @@ int lxc_monitor_open(const char *lxcpath)
...
@@ -199,23 +208,25 @@ int lxc_monitor_open(const char *lxcpath)
if
(
len
>=
sizeof
(
addr
.
sun_path
)
-
1
)
{
if
(
len
>=
sizeof
(
addr
.
sun_path
)
-
1
)
{
ret
=
-
1
;
ret
=
-
1
;
errno
=
ENAMETOOLONG
;
errno
=
ENAMETOOLONG
;
goto
err1
;
goto
on_error
;
}
}
for
(
retry
=
0
;
retry
<
sizeof
(
backoff_ms
)
/
sizeof
(
backoff_ms
[
0
]);
retry
++
)
{
for
(
retry
=
0
;
retry
<
sizeof
(
backoff_ms
)
/
sizeof
(
backoff_ms
[
0
]);
retry
++
)
{
ret
=
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
);
ret
=
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
);
if
(
ret
==
0
||
errno
!=
ECONNREFUSED
)
if
(
ret
==
0
||
errno
!=
ECONNREFUSED
)
break
;
break
;
ERROR
(
"
connect : backing off %d
"
,
backoff_ms
[
retry
]);
ERROR
(
"
Failed to connect to monitor socket. Retrying in %d ms.
"
,
backoff_ms
[
retry
]);
usleep
(
backoff_ms
[
retry
]
*
1000
);
usleep
(
backoff_ms
[
retry
]
*
1000
);
}
}
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"
connect : %s
"
,
strerror
(
errno
));
ERROR
(
"
Failed to connect to monitor socket: %s.
"
,
strerror
(
errno
));
goto
err1
;
goto
on_error
;
}
}
return
fd
;
return
fd
;
err1:
on_error:
close
(
fd
);
close
(
fd
);
return
ret
;
return
ret
;
}
}
...
@@ -232,22 +243,23 @@ int lxc_monitor_read_fdset(struct pollfd *fds, nfds_t nfds, struct lxc_msg *msg,
...
@@ -232,22 +243,23 @@ int lxc_monitor_read_fdset(struct pollfd *fds, nfds_t nfds, struct lxc_msg *msg,
else
if
(
ret
==
0
)
else
if
(
ret
==
0
)
return
-
2
;
// timed out
return
-
2
;
// timed out
/*
only read from the first ready fd, the others will remain ready
/*
Only read from the first ready fd, the others will remain ready for
*
for when this routine is called again
*
when this routine is called again.
*/
*/
for
(
i
=
0
;
i
<
nfds
;
i
++
)
{
for
(
i
=
0
;
i
<
nfds
;
i
++
)
{
if
(
fds
[
i
].
revents
!=
0
)
{
if
(
fds
[
i
].
revents
!=
0
)
{
fds
[
i
].
revents
=
0
;
fds
[
i
].
revents
=
0
;
ret
=
recv
(
fds
[
i
].
fd
,
msg
,
sizeof
(
*
msg
),
0
);
ret
=
recv
(
fds
[
i
].
fd
,
msg
,
sizeof
(
*
msg
),
0
);
if
(
ret
<=
0
)
{
if
(
ret
<=
0
)
{
SYSERROR
(
"client failed to recv (monitord died?) %s"
,
SYSERROR
(
"Failed to receive message. Did monitord die?: %s."
,
strerror
(
errno
));
strerror
(
errno
));
return
-
1
;
return
-
1
;
}
}
return
ret
;
return
ret
;
}
}
}
}
SYSERROR
(
"no ready fd found?"
);
SYSERROR
(
"No ready fd found."
);
return
-
1
;
return
-
1
;
}
}
...
@@ -267,19 +279,18 @@ int lxc_monitor_read(int fd, struct lxc_msg *msg)
...
@@ -267,19 +279,18 @@ int lxc_monitor_read(int fd, struct lxc_msg *msg)
return
lxc_monitor_read_timeout
(
fd
,
msg
,
-
1
);
return
lxc_monitor_read_timeout
(
fd
,
msg
,
-
1
);
}
}
#define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
#define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
/*
u
sed to spawn a monitord either on startup of a daemon container, or when
/*
U
sed to spawn a monitord either on startup of a daemon container, or when
* lxc-monitor starts
* lxc-monitor starts
.
*/
*/
int
lxc_monitord_spawn
(
const
char
*
lxcpath
)
int
lxc_monitord_spawn
(
const
char
*
lxcpath
)
{
{
pid_t
pid1
,
pid2
;
pid_t
pid1
,
pid2
;
int
pipefd
[
2
];
int
pipefd
[
2
];
char
pipefd_str
[
11
];
char
pipefd_str
[
11
];
char
*
const
args
[]
=
{
char
*
const
args
[]
=
{
LXC_MONITORD_PATH
,
LXC_MONITORD_PATH
,
(
char
*
)
lxcpath
,
(
char
*
)
lxcpath
,
pipefd_str
,
pipefd_str
,
...
@@ -289,50 +300,60 @@ int lxc_monitord_spawn(const char *lxcpath)
...
@@ -289,50 +300,60 @@ int lxc_monitord_spawn(const char *lxcpath)
/* double fork to avoid zombies when monitord exits */
/* double fork to avoid zombies when monitord exits */
pid1
=
fork
();
pid1
=
fork
();
if
(
pid1
<
0
)
{
if
(
pid1
<
0
)
{
SYSERROR
(
"
failed to fork
"
);
SYSERROR
(
"
Failed to fork().
"
);
return
-
1
;
return
-
1
;
}
}
if
(
pid1
)
{
if
(
pid1
)
{
DEBUG
(
"Going to wait for pid %d."
,
pid1
);
if
(
waitpid
(
pid1
,
NULL
,
0
)
!=
pid1
)
if
(
waitpid
(
pid1
,
NULL
,
0
)
!=
pid1
)
return
-
1
;
return
-
1
;
return
0
;
return
0
;
}
}
if
(
pipe
(
pipefd
)
<
0
)
{
if
(
pipe
(
pipefd
)
<
0
)
{
SYSERROR
(
"
failed to create pipe
"
);
SYSERROR
(
"
Failed to create pipe.
"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
pid2
=
fork
();
pid2
=
fork
();
if
(
pid2
<
0
)
{
if
(
pid2
<
0
)
{
SYSERROR
(
"
failed to fork
"
);
SYSERROR
(
"
Failed to fork().
"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
if
(
pid2
)
{
if
(
pid2
)
{
char
c
;
char
c
;
/*
wait for daemon to create socket
*/
/*
Wait for daemon to create socket.
*/
close
(
pipefd
[
1
]);
close
(
pipefd
[
1
]);
/* sync with child, we're ignoring the return from read
/* Sync with child, we're ignoring the return from read
* because regardless if it works or not, either way we've
* because regardless if it works or not, either way we've
* synced with the child process. the if-empty-statement
* synced with the child process. the if-empty-statement
* construct is to quiet the warn-unused-result warning.
* construct is to quiet the warn-unused-result warning.
*/
*/
if
(
read
(
pipefd
[
0
],
&
c
,
1
))
if
(
read
(
pipefd
[
0
],
&
c
,
1
))
;
;
close
(
pipefd
[
0
]);
close
(
pipefd
[
0
]);
exit
(
EXIT_SUCCESS
);
exit
(
EXIT_SUCCESS
);
}
}
if
(
setsid
()
<
0
)
{
if
(
setsid
()
<
0
)
{
SYSERROR
(
"
failed to setsid
"
);
SYSERROR
(
"
Failed to setsid().
"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
lxc_check_inherited
(
NULL
,
true
,
pipefd
[
1
]);
lxc_check_inherited
(
NULL
,
true
,
pipefd
[
1
]);
if
(
null_stdfds
()
<
0
)
if
(
null_stdfds
()
<
0
)
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
close
(
pipefd
[
0
]);
close
(
pipefd
[
0
]);
sprintf
(
pipefd_str
,
"%d"
,
pipefd
[
1
]);
sprintf
(
pipefd_str
,
"%d"
,
pipefd
[
1
]);
execvp
(
args
[
0
],
args
);
execvp
(
args
[
0
],
args
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
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