[CRIU] [PATCH 2/2] net: sockets -- Don't spam log with known errors
Cyrill Gorcunov
gorcunov at gmail.com
Wed Oct 24 00:24:20 MSK 2018
For example if diag module is not built then we should
not spam with error message but we will print an error
if only a particular socket is really used.
v2:
- continue passing @ns into error handler because it should
be balanced with receieve handler by number of arguments;
while we don't use it yet in our handlers better to reserve
it immediately for future use;
- strictly speaking probing raw diag module has not much sense
by now -- the kernel doesn't support its autoloading and I think
I should address this problem someday; still for code consistency
we should do the same things for all modules;
- i removed @has_sk_diag_packet from sockets code: actually I don't
understand how it helps tests at all;
The rest is obvious.
Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
criu/include/libnetlink.h | 2 +-
criu/libnetlink.c | 10 ++--
criu/sockets.c | 111 ++++++++++++++++++++++----------------
3 files changed, 70 insertions(+), 53 deletions(-)
diff --git a/criu/include/libnetlink.h b/criu/include/libnetlink.h
index bf2eb24740b0..f21a0e750337 100644
--- a/criu/include/libnetlink.h
+++ b/criu/include/libnetlink.h
@@ -6,7 +6,7 @@
struct ns_id;
extern int do_rtnl_req(int nl, void *req, int size,
int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
- int (*error_callback)(int err, void *), struct ns_id *ns, void *);
+ int (*error_callback)(int err, struct ns_id *ns, void *), struct ns_id *ns, void *);
extern int addattr_l(struct nlmsghdr *n, int maxlen, int type,
const void *data, int alen);
diff --git a/criu/libnetlink.c b/criu/libnetlink.c
index 2ce4a38262d4..60e98e3460dc 100644
--- a/criu/libnetlink.c
+++ b/criu/libnetlink.c
@@ -12,7 +12,7 @@
static int nlmsg_receive(char *buf, int len,
int (*cb)(struct nlmsghdr *, struct ns_id *ns, void *),
- int (*err_cb)(int, void *), struct ns_id *ns, void *arg)
+ int (*err_cb)(int, struct ns_id *, void *), struct ns_id *ns, void *arg)
{
struct nlmsghdr *hdr;
@@ -22,7 +22,7 @@ static int nlmsg_receive(char *buf, int len,
if (hdr->nlmsg_type == NLMSG_DONE) {
int *len = (int *)NLMSG_DATA(hdr);
if (*len < 0)
- return err_cb(*len, arg);
+ return err_cb(*len, ns, arg);
return 0;
}
if (hdr->nlmsg_type == NLMSG_ERROR) {
@@ -36,7 +36,7 @@ static int nlmsg_receive(char *buf, int len,
if (err->error == 0)
return 0;
- return err_cb(err->error, arg);
+ return err_cb(err->error, ns, arg);
}
if (cb(hdr, ns, arg))
return -1;
@@ -45,7 +45,7 @@ static int nlmsg_receive(char *buf, int len,
return 1;
}
-static int rtnl_return_err(int err, void *arg)
+static int rtnl_return_err(int err, struct ns_id *ns, void *arg)
{
errno = -err;
pr_perror("ERROR %d reported by netlink", err);
@@ -54,7 +54,7 @@ static int rtnl_return_err(int err, void *arg)
int do_rtnl_req(int nl, void *req, int size,
int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
- int (*error_callback)(int err, void *), struct ns_id *ns, void *arg)
+ int (*error_callback)(int err, struct ns_id *ns, void *arg), struct ns_id *ns, void *arg)
{
struct msghdr msg;
struct sockaddr_nl nladdr;
diff --git a/criu/sockets.c b/criu/sockets.c
index dd40a777eb6a..d300a7dde63d 100644
--- a/criu/sockets.c
+++ b/criu/sockets.c
@@ -213,7 +213,7 @@ static int probe_recv_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
return -1;
}
-static int probe_err(int err, void *arg)
+static int probe_err(int err, struct ns_id *ns, void *arg)
{
int expected_err = *(int *)arg;
@@ -717,18 +717,57 @@ static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
static int do_collect_req(int nl, struct sock_diag_req *req, int size,
int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
+ int (*error_callback)(int err, struct ns_id *ns, void *),
struct ns_id *ns, void *arg)
{
- int tmp;
-
- tmp = do_rtnl_req(nl, req, size, receive_callback, NULL, ns, arg);
-
+ int tmp = do_rtnl_req(nl, req, size, receive_callback, error_callback, ns, arg);
if (tmp == 0)
set_collect_bit(req->r.n.sdiag_family, req->r.n.sdiag_protocol);
-
return tmp;
}
+static int collect_err(int err, struct ns_id *ns, void *arg)
+{
+ struct sock_diag_greq *gr = arg;
+ char family[32], proto[32];
+ char msg[256];
+
+ /*
+ * If module is not compiled or unloaded,
+ * we should simply pass error up to a caller
+ * which then warn a user.
+ */
+ if (err == -ENOENT)
+ return -ENOENT;
+
+ /*
+ * Diag modules such as unix, packet, netlink
+ * may return EINVAL on older kernels.
+ */
+ if (err == -EINVAL) {
+ if (gr->family == AF_UNIX ||
+ gr->family == AF_PACKET ||
+ gr->family == AF_NETLINK)
+ return -EINVAL;
+ }
+
+ /*
+ * Rest is more serious, just print enough information.
+ * In case if everything is OK -- point as well.
+ */
+ snprintf(msg, sizeof(msg),
+ "Sockects collect procedure family %s proto %s\n",
+ socket_family_name(gr->family, family, sizeof(family)),
+ socket_proto_name(gr->protocol, proto, sizeof(proto)));
+
+ if (!err)
+ pr_info("%s: OK\n", msg);
+ else
+ pr_err("%s: %s\n", msg, strerror(-err));
+
+ return err;
+}
+
int collect_sockets(struct ns_id *ns)
{
int err = 0, tmp;
@@ -747,7 +786,7 @@ int collect_sockets(struct ns_id *ns)
req.r.u.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_VFS |
UDIAG_SHOW_PEER | UDIAG_SHOW_ICONS |
UDIAG_SHOW_RQLEN;
- tmp = do_collect_req(nl, &req, sizeof(req), unix_receive_one, ns, NULL);
+ tmp = do_collect_req(nl, &req, sizeof(req), unix_receive_one, collect_err, ns, &req.r.u);
if (tmp)
err = tmp;
@@ -760,7 +799,7 @@ int collect_sockets(struct ns_id *ns)
(1 << TCP_FIN_WAIT1) | (1 << TCP_FIN_WAIT2) |
(1 << TCP_CLOSE_WAIT) | (1 << TCP_LAST_ACK) |
(1 << TCP_CLOSING) | (1 << TCP_SYN_SENT);
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
if (tmp)
err = tmp;
@@ -769,7 +808,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDP;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
if (tmp)
err = tmp;
@@ -778,7 +817,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDPLITE;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
if (tmp)
err = tmp;
@@ -787,17 +826,9 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_RAW;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
- if (kdat.has_sk_diag_packet < 2) {
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
- if (tmp == -ENOENT)
- kdat.has_sk_diag_packet = 2;
- } else
- tmp = -ENOENT;
- if (tmp) {
- pr_warn("The current kernel doesn't support ipv4 raw_diag module\n");
- if (tmp != -ENOENT)
- err = tmp;
- }
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
+ if (tmp)
+ err = tmp;
/* Collect IPv6 TCP sockets */
req.r.i.sdiag_family = AF_INET6;
@@ -808,7 +839,7 @@ int collect_sockets(struct ns_id *ns)
(1 << TCP_FIN_WAIT1) | (1 << TCP_FIN_WAIT2) |
(1 << TCP_CLOSE_WAIT) | (1 << TCP_LAST_ACK) |
(1 << TCP_CLOSING) | (1 << TCP_SYN_SENT);
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
if (tmp)
err = tmp;
@@ -817,7 +848,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDP;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
if (tmp)
err = tmp;
@@ -826,7 +857,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDPLITE;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
if (tmp)
err = tmp;
@@ -835,38 +866,24 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_RAW;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
- if (kdat.has_sk_diag_packet < 2) {
- tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
- if (tmp == -ENOENT)
- kdat.has_sk_diag_packet = 2;
- } else
- tmp = -ENOENT;
- if (tmp) {
- pr_warn("The current kernel doesn't support ipv6 raw_diag module\n");
- if (tmp != -ENOENT)
- err = tmp;
- }
+ tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, collect_err, ns, &req.r.i);
+ if (tmp)
+ err = tmp;
req.r.p.sdiag_family = AF_PACKET;
req.r.p.sdiag_protocol = 0;
req.r.p.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MCLIST |
PACKET_SHOW_FANOUT | PACKET_SHOW_RING_CFG;
- tmp = do_collect_req(nl, &req, sizeof(req), packet_receive_one, ns, NULL);
- if (tmp) {
- pr_warn("The current kernel doesn't support packet_diag\n");
- if (tmp != -ENOENT) /* Fedora 19 */
- err = tmp;
- }
+ tmp = do_collect_req(nl, &req, sizeof(req), packet_receive_one, collect_err, ns, &req.r.p);
+ if (tmp)
+ err = tmp;
req.r.n.sdiag_family = AF_NETLINK;
req.r.n.sdiag_protocol = NDIAG_PROTO_ALL;
req.r.n.ndiag_show = NDIAG_SHOW_GROUPS;
- tmp = do_collect_req(nl, &req, sizeof(req), netlink_receive_one, ns, NULL);
- if (tmp) {
- pr_warn("The current kernel doesn't support netlink_diag\n");
- if (ns->ns_pid == 0 || tmp != -ENOENT) /* Fedora 19 */
- err = tmp;
- }
+ tmp = do_collect_req(nl, &req, sizeof(req), netlink_receive_one, collect_err, ns, &req.r.n);
+ if (tmp)
+ err = tmp;
/* don't need anymore */
close(nl);
--
2.17.2
More information about the CRIU
mailing list