]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/commands_utils.c
commands: add missing translation
[mirror_lxc.git] / src / lxc / commands_utils.c
CommitLineData
92e35018
CB
1/* liblxcapi
2 *
3 * Copyright © 2017 Christian Brauner <christian.brauner@ubuntu.com>.
4 * Copyright © 2017 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#define _GNU_SOURCE
bbf5cf35 21#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
92e35018 22#include <errno.h>
bbf5cf35 23#include <inttypes.h>
92e35018 24#include <stdio.h>
bbf5cf35 25#include <stdlib.h>
92e35018
CB
26#include <string.h>
27#include <unistd.h>
28#include <sys/socket.h>
29#include <sys/un.h>
30
31#include "commands.h"
32#include "commands_utils.h"
33#include "log.h"
34#include "monitor.h"
35#include "state.h"
bbf5cf35 36#include "utils.h"
92e35018
CB
37
38lxc_log_define(lxc_commands_utils, lxc);
39
40int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout)
41{
42 int ret;
43 struct lxc_msg msg;
44 struct timeval out;
45
46 memset(&out, 0, sizeof(out));
47 out.tv_sec = timeout;
48 ret = setsockopt(state_client_fd, SOL_SOCKET, SO_RCVTIMEO,
49 (const void *)&out, sizeof(out));
50 if (ret < 0) {
51 SYSERROR("Failed to set %ds timeout on containter state socket", timeout);
52 return -1;
53 }
54
55 memset(&msg, 0, sizeof(msg));
56
57again:
58 ret = recv(state_client_fd, &msg, sizeof(msg), 0);
59 if (ret < 0) {
60 if (errno == EINTR)
61 goto again;
62
63 ERROR("failed to receive message: %s", strerror(errno));
64 return -1;
65 }
66
67 if (ret == 0) {
68 ERROR("length of message was 0");
69 return -1;
70 }
71
72 TRACE("received state %s from state client %d",
73 lxc_state2str(msg.value), state_client_fd);
74
75 return msg.value;
76}
77
78/* Register a new state client and retrieve state from command socket. */
79int lxc_cmd_sock_get_state(const char *name, const char *lxcpath,
80 lxc_state_t states[MAX_STATE], int timeout)
81{
82 int ret;
83 int state_client_fd;
84
85 ret = lxc_cmd_add_state_client(name, lxcpath, states, &state_client_fd);
86 if (ret < 0)
87 return -1;
88
89 if (ret < MAX_STATE)
90 return ret;
91
92 ret = lxc_cmd_sock_rcv_state(state_client_fd, timeout);
93 close(state_client_fd);
94 return ret;
95}
bbf5cf35
CB
96
97int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
98 const char *lxcpath,
99 const char *hashed_sock_name,
100 const char *suffix)
101{
102 const char *name;
103 char *tmppath;
104 size_t tmplen;
105 uint64_t hash;
106 int ret;
107
108 name = lxcname;
109 if (!name)
110 name = "";
111
112 if (hashed_sock_name != NULL) {
113 ret =
114 snprintf(path, len, "lxc/%s/%s", hashed_sock_name, suffix);
115 if (ret < 0 || ret >= len) {
116 ERROR("Failed to create abstract socket name");
117 return -1;
118 }
119 return 0;
120 }
121
122 if (!lxcpath) {
123 lxcpath = lxc_global_config_value("lxc.lxcpath");
124 if (!lxcpath) {
125 ERROR("Failed to allocate memory");
126 return -1;
127 }
128 }
129
130 ret = snprintf(path, len, "%s/%s/%s", lxcpath, name, suffix);
131 if (ret < 0) {
132 ERROR("Failed to create abstract socket name");
133 return -1;
134 }
135 if (ret < len)
136 return 0;
137
138 /* ret >= len; lxcpath or name is too long. hash both */
139 tmplen = strlen(name) + strlen(lxcpath) + 2;
140 tmppath = alloca(tmplen);
141 ret = snprintf(tmppath, tmplen, "%s/%s", lxcpath, name);
142 if (ret < 0 || (size_t)ret >= tmplen) {
143 ERROR("Failed to create abstract socket name");
144 return -1;
145 }
146
147 hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
148 ret = snprintf(path, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
149 if (ret < 0 || ret >= len) {
150 ERROR("Failed to create abstract socket name");
151 return -1;
152 }
153
154 return 0;
155}