mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-14 07:33:48 +00:00
Merge pull request #2691 from 2xsec/bugfix
Some redundancy codes of abstract unix socket are removed with log cleanups.
This commit is contained in:
commit
a22d1745d7
@ -1244,24 +1244,17 @@ out_close:
|
|||||||
|
|
||||||
int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
|
int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
|
||||||
{
|
{
|
||||||
int fd, len, ret;
|
int fd, ret;
|
||||||
char path[LXC_AUDS_ADDR_LEN] = {0};
|
char path[LXC_AUDS_ADDR_LEN] = {0};
|
||||||
char *offset = &path[1];
|
|
||||||
|
|
||||||
/* -2 here because this is an abstract unix socket so it needs a
|
ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, NULL, suffix);
|
||||||
* leading \0, and we null terminate, so it needs a trailing \0.
|
|
||||||
* Although null termination isn't required by the API, we do it anyway
|
|
||||||
* because we print the sockname out sometimes.
|
|
||||||
*/
|
|
||||||
len = sizeof(path) - 2;
|
|
||||||
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath, NULL, suffix);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
TRACE("Creating abstract unix socket \"%s\"", offset);
|
TRACE("Creating abstract unix socket \"%s\"", &path[1]);
|
||||||
|
|
||||||
fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
|
fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
SYSERROR("Failed to create command socket %s", offset);
|
SYSERROR("Failed to create command socket %s", &path[1]);
|
||||||
if (errno == EADDRINUSE)
|
if (errno == EADDRINUSE)
|
||||||
ERROR("Container \"%s\" appears to be already running", name);
|
ERROR("Container \"%s\" appears to be already running", name);
|
||||||
|
|
||||||
|
@ -96,24 +96,38 @@ int lxc_cmd_sock_get_state(const char *name, const char *lxcpath,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
|
int lxc_make_abstract_socket_name(char *path, size_t pathlen,
|
||||||
|
const char *lxcname,
|
||||||
const char *lxcpath,
|
const char *lxcpath,
|
||||||
const char *hashed_sock_name,
|
const char *hashed_sock_name,
|
||||||
const char *suffix)
|
const char *suffix)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
char *offset;
|
||||||
char *tmppath;
|
char *tmppath;
|
||||||
|
size_t len;
|
||||||
size_t tmplen;
|
size_t tmplen;
|
||||||
uint64_t hash;
|
uint64_t hash;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
offset = &path[1];
|
||||||
|
|
||||||
|
/* -2 here because this is an abstract unix socket so it needs a
|
||||||
|
* leading \0, and we null terminate, so it needs a trailing \0.
|
||||||
|
* Although null termination isn't required by the API, we do it anyway
|
||||||
|
* because we print the sockname out sometimes.
|
||||||
|
*/
|
||||||
|
len = pathlen -2;
|
||||||
|
|
||||||
name = lxcname;
|
name = lxcname;
|
||||||
if (!name)
|
if (!name)
|
||||||
name = "";
|
name = "";
|
||||||
|
|
||||||
if (hashed_sock_name != NULL) {
|
if (hashed_sock_name != NULL) {
|
||||||
ret =
|
ret = snprintf(offset, len, "lxc/%s/%s", hashed_sock_name, suffix);
|
||||||
snprintf(path, len, "lxc/%s/%s", hashed_sock_name, suffix);
|
|
||||||
if (ret < 0 || ret >= len) {
|
if (ret < 0 || ret >= len) {
|
||||||
ERROR("Failed to create abstract socket name");
|
ERROR("Failed to create abstract socket name");
|
||||||
return -1;
|
return -1;
|
||||||
@ -129,7 +143,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = snprintf(path, len, "%s/%s/%s", lxcpath, name, suffix);
|
ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ERROR("Failed to create abstract socket name");
|
ERROR("Failed to create abstract socket name");
|
||||||
return -1;
|
return -1;
|
||||||
@ -147,7 +161,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
|
hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
|
||||||
ret = snprintf(path, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
|
ret = snprintf(offset, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
|
||||||
if (ret < 0 || ret >= len) {
|
if (ret < 0 || ret >= len) {
|
||||||
ERROR("Failed to create abstract socket name");
|
ERROR("Failed to create abstract socket name");
|
||||||
return -1;
|
return -1;
|
||||||
@ -161,15 +175,8 @@ int lxc_cmd_connect(const char *name, const char *lxcpath,
|
|||||||
{
|
{
|
||||||
int ret, client_fd;
|
int ret, client_fd;
|
||||||
char path[LXC_AUDS_ADDR_LEN] = {0};
|
char path[LXC_AUDS_ADDR_LEN] = {0};
|
||||||
char *offset = &path[1];
|
|
||||||
|
|
||||||
/* -2 here because this is an abstract unix socket so it needs a
|
ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath,
|
||||||
* leading \0, and we null terminate, so it needs a trailing \0.
|
|
||||||
* Although null termination isn't required by the API, we do it anyway
|
|
||||||
* because we print the sockname out sometimes.
|
|
||||||
*/
|
|
||||||
size_t len = sizeof(path) - 2;
|
|
||||||
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath,
|
|
||||||
hashed_sock_name, suffix);
|
hashed_sock_name, suffix);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
|
int lxc_make_abstract_socket_name(char *path, size_t pathlen,
|
||||||
|
const char *lxcname,
|
||||||
const char *lxcpath,
|
const char *lxcpath,
|
||||||
const char *hashed_sock_name,
|
const char *hashed_sock_name,
|
||||||
const char *suffix);
|
const char *suffix);
|
||||||
|
@ -73,7 +73,7 @@ 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 || (size_t)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;
|
||||||
}
|
}
|
||||||
@ -86,7 +86,7 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
|
|||||||
}
|
}
|
||||||
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 || (size_t)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;
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
|
|||||||
ret = lxc_write_nointr(fd, msg, sizeof(*msg));
|
ret = lxc_write_nointr(fd, msg, sizeof(*msg));
|
||||||
if (ret != sizeof(*msg)) {
|
if (ret != sizeof(*msg)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
SYSERROR("Failed to write to monitor fifo \"%s\".", fifo_path);
|
SYSERROR("Failed to write to monitor fifo \"%s\"", fifo_path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +168,8 @@ int lxc_monitor_close(int fd)
|
|||||||
* have a maximum of 106 chars. But to not break backwards compatibility we keep
|
* have a maximum of 106 chars. But to not break backwards compatibility we keep
|
||||||
* the limit at 105.
|
* the limit at 105.
|
||||||
*/
|
*/
|
||||||
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 *path;
|
char *path;
|
||||||
@ -185,7 +186,7 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
|
|||||||
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 || (size_t)ret >= len) {
|
if (ret < 0 || (size_t)ret >= len) {
|
||||||
ERROR("failed to create name for monitor socket");
|
ERROR("Failed to create name for monitor socket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,15 +199,22 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
|
|||||||
hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
|
hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
|
||||||
ret = snprintf(addr->sun_path, len, "@lxc/%016" PRIx64 "/%s", hash, lxcpath);
|
ret = snprintf(addr->sun_path, len, "@lxc/%016" PRIx64 "/%s", hash, lxcpath);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ERROR("failed to create hashed name for monitor socket");
|
ERROR("Failed to create hashed name for monitor socket");
|
||||||
return -1;
|
goto on_error;
|
||||||
|
} else if ((size_t)ret >= len) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
SYSERROR("The name of monitor socket too long (%d bytes)", ret);
|
||||||
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* replace @ with \0 */
|
/* replace @ with \0 */
|
||||||
addr->sun_path[0] = '\0';
|
addr->sun_path[0] = '\0';
|
||||||
INFO("using monitor socket name \"%s\" (length of socket name %zu must be <= %zu)", &addr->sun_path[1], strlen(&addr->sun_path[1]), sizeof(addr->sun_path) - 3);
|
INFO("Using monitor socket name \"%s\" (length of socket name %zu must be <= %zu)", &addr->sun_path[1], strlen(&addr->sun_path[1]), sizeof(addr->sun_path) - 3);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lxc_monitor_open(const char *lxcpath)
|
int lxc_monitor_open(const char *lxcpath)
|
||||||
@ -214,19 +222,12 @@ int lxc_monitor_open(const char *lxcpath)
|
|||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
int fd;
|
int fd;
|
||||||
size_t retry;
|
size_t retry;
|
||||||
size_t len;
|
|
||||||
int backoff_ms[] = {10, 50, 100};
|
int 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;
|
||||||
|
|
||||||
len = strlen(&addr.sun_path[1]);
|
DEBUG("Opening monitor socket %s with len %zu", &addr.sun_path[1], strlen(&addr.sun_path[1]));
|
||||||
DEBUG("opening monitor socket %s with len %zu", &addr.sun_path[1], len);
|
|
||||||
if (len >= sizeof(addr.sun_path) - 1) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
SYSERROR("The name of monitor socket too long (%zu bytes)", len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (retry = 0; retry < sizeof(backoff_ms) / sizeof(backoff_ms[0]); retry++) {
|
for (retry = 0; retry < sizeof(backoff_ms) / sizeof(backoff_ms[0]); retry++) {
|
||||||
fd = lxc_abstract_unix_connect(addr.sun_path);
|
fd = lxc_abstract_unix_connect(addr.sun_path);
|
||||||
@ -272,7 +273,7 @@ int lxc_monitor_read_fdset(struct pollfd *fds, nfds_t nfds, struct lxc_msg *msg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSERROR("No ready fd found.");
|
SYSERROR("No ready fd found");
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -315,33 +316,33 @@ 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);
|
DEBUG("Going to wait for pid %d", pid1);
|
||||||
|
|
||||||
if (waitpid(pid1, NULL, 0) != pid1)
|
if (waitpid(pid1, NULL, 0) != pid1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
DEBUG("Finished waiting on pid %d.", pid1);
|
DEBUG("Finished waiting on pid %d", pid1);
|
||||||
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) {
|
||||||
DEBUG("Trying to sync with child process.");
|
DEBUG("Trying to sync with child process");
|
||||||
char c;
|
char c;
|
||||||
/* Wait for daemon to create socket. */
|
/* Wait for daemon to create socket. */
|
||||||
close(pipefd[1]);
|
close(pipefd[1]);
|
||||||
@ -356,18 +357,18 @@ int lxc_monitord_spawn(const char *lxcpath)
|
|||||||
|
|
||||||
close(pipefd[0]);
|
close(pipefd[0]);
|
||||||
|
|
||||||
DEBUG("Successfully synced with child process.");
|
DEBUG("Successfully synced with child process");
|
||||||
_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], 1);
|
lxc_check_inherited(NULL, true, &pipefd[1], 1);
|
||||||
if (null_stdfds() < 0) {
|
if (null_stdfds() < 0) {
|
||||||
SYSERROR("Failed to dup2() standard file descriptors to /dev/null.");
|
SYSERROR("Failed to dup2() standard file descriptors to /dev/null");
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,14 +376,14 @@ int lxc_monitord_spawn(const char *lxcpath)
|
|||||||
|
|
||||||
ret = snprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]);
|
ret = snprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]);
|
||||||
if (ret < 0 || ret >= sizeof(pipefd_str)) {
|
if (ret < 0 || ret >= sizeof(pipefd_str)) {
|
||||||
ERROR("Failed to create pid argument to pass to monitord.");
|
ERROR("Failed to create pid argument to pass to monitord");
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("Using pipe file descriptor %d for monitord.", pipefd[1]);
|
DEBUG("Using pipe file descriptor %d for monitord", pipefd[1]);
|
||||||
|
|
||||||
execvp(args[0], args);
|
execvp(args[0], args);
|
||||||
SYSERROR("failed to exec lxc-monitord");
|
SYSERROR("Failed to exec lxc-monitord");
|
||||||
|
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user