commands: backport robust infrastructure

parent c458e212
...@@ -25,16 +25,24 @@ ...@@ -25,16 +25,24 @@
#define __LXC_COMMANDS_H #define __LXC_COMMANDS_H
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#include "lxccontainer.h"
#include "state.h" #include "state.h"
#define LXC_CMD_DATA_MAX (MAXPATHLEN * 2) #define LXC_CMD_DATA_MAX (MAXPATHLEN * 2)
/* https://developer.gnome.org/glib/2.28/glib-Type-Conversion-Macros.html */ /* Length of abstract unix domain socket socket address. */
#define INT_TO_PTR(n) ((void *)(long)(n)) #define LXC_AUDS_ADDR_LEN sizeof(((struct sockaddr_un *)0)->sun_path)
#define PTR_TO_INT(p) ((int)(long)(p))
/* pointer conversion macros */
#define PTR_TO_INT(p) ((int)((intptr_t)(p)))
#define INT_TO_PTR(u) ((void *)((intptr_t)(u)))
#define PTR_TO_INTMAX(p) ((intmax_t)((intptr_t)(p)))
#define INTMAX_TO_PTR(u) ((void *)((intptr_t)(u)))
typedef enum { typedef enum {
LXC_CMD_CONSOLE, LXC_CMD_CONSOLE,
......
...@@ -17,20 +17,23 @@ ...@@ -17,20 +17,23 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#define _GNU_SOURCE #ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */ #define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h>
#include "af_unix.h" #include "af_unix.h"
#include "commands.h" #include "commands.h"
#include "commands_utils.h" #include "commands_utils.h"
#include "config.h"
#include "initutils.h" #include "initutils.h"
#include "log.h" #include "log.h"
#include "lxclock.h" #include "lxclock.h"
...@@ -52,7 +55,7 @@ int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout) ...@@ -52,7 +55,7 @@ int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout)
ret = setsockopt(state_client_fd, SOL_SOCKET, SO_RCVTIMEO, ret = setsockopt(state_client_fd, SOL_SOCKET, SO_RCVTIMEO,
(const void *)&out, sizeof(out)); (const void *)&out, sizeof(out));
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set %ds timeout on containter " SYSERROR("Failed to set %ds timeout on container "
"state socket", "state socket",
timeout); timeout);
return -1; return -1;
...@@ -98,24 +101,38 @@ int lxc_cmd_sock_get_state(const char *name, const char *lxcpath, ...@@ -98,24 +101,38 @@ int lxc_cmd_sock_get_state(const char *name, const char *lxcpath,
return ret; return ret;
} }
int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname, int lxc_make_abstract_socket_name(char *path, size_t pathlen,
const char *lxcname,
const char *lxcpath, const char *lxcpath,
const char *hashed_sock_name, const char *hashed_sock_name,
const char *suffix) const char *suffix)
{ {
const char *name; const char *name;
char *offset;
char *tmppath; char *tmppath;
size_t len;
size_t tmplen; size_t tmplen;
uint64_t hash; uint64_t hash;
int ret; int ret;
if (!path)
return -1;
offset = &path[1];
/* -2 here because this is an abstract unix socket so it needs a
* leading \0, and we null terminate, so it needs a trailing \0.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
len = pathlen - 2;
name = lxcname; name = lxcname;
if (!name) if (!name)
name = ""; name = "";
if (hashed_sock_name != NULL) { if (hashed_sock_name != NULL) {
ret = ret = snprintf(offset, len, "lxc/%s/%s", hashed_sock_name, suffix);
snprintf(path, len, "lxc/%s/%s", hashed_sock_name, suffix);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len) {
ERROR("Failed to create abstract socket name"); ERROR("Failed to create abstract socket name");
return -1; return -1;
...@@ -131,7 +148,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname, ...@@ -131,7 +148,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
} }
} }
ret = snprintf(path, len, "%s/%s/%s", lxcpath, name, suffix); ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create abstract socket name"); ERROR("Failed to create abstract socket name");
return -1; return -1;
...@@ -149,7 +166,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname, ...@@ -149,7 +166,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
} }
hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT); hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
ret = snprintf(path, len, "lxc/%016" PRIx64 "/%s", hash, suffix); ret = snprintf(offset, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len) {
ERROR("Failed to create abstract socket name"); ERROR("Failed to create abstract socket name");
return -1; return -1;
...@@ -162,27 +179,17 @@ int lxc_cmd_connect(const char *name, const char *lxcpath, ...@@ -162,27 +179,17 @@ int lxc_cmd_connect(const char *name, const char *lxcpath,
const char *hashed_sock_name, const char *suffix) const char *hashed_sock_name, const char *suffix)
{ {
int ret, client_fd; int ret, client_fd;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = {0}; char path[LXC_AUDS_ADDR_LEN] = {0};
char *offset = &path[1];
/* -2 here because this is an abstract unix socket so it needs a ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath,
* leading \0, and we null terminate, so it needs a trailing \0.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
size_t len = sizeof(path) - 2;
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath,
hashed_sock_name, suffix); hashed_sock_name, suffix);
if (ret < 0) if (ret < 0)
return -1; return -1;
/* Get new client fd. */ /* Get new client fd. */
client_fd = lxc_abstract_unix_connect(path); client_fd = lxc_abstract_unix_connect(path);
if (client_fd < 0) { if (client_fd < 0)
if (errno == ECONNREFUSED)
return -ECONNREFUSED;
return -1; return -1;
}
return client_fd; return client_fd;
} }
...@@ -218,6 +225,6 @@ int lxc_add_state_client(int state_client_fd, struct lxc_handler *handler, ...@@ -218,6 +225,6 @@ int lxc_add_state_client(int state_client_fd, struct lxc_handler *handler,
return state; return state;
} }
TRACE("added state client %d to state client list", state_client_fd); TRACE("Added state client %d to state client list", state_client_fd);
return MAX_STATE; return MAX_STATE;
} }
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
#include "state.h" #include "state.h"
#include "commands.h" #include "commands.h"
int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname, int lxc_make_abstract_socket_name(char *path, size_t pathlen,
const char *lxcname,
const char *lxcpath, const char *lxcpath,
const char *hashed_sock_name, const char *hashed_sock_name,
const char *suffix); const char *suffix);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment