[CRIU] [PATCH 1/2] nlk: Add error callback to do_rtnl_req

Pavel Emelyanov xemul at parallels.com
Wed Jan 14 06:28:24 PST 2015


In the next patch we will need to care about the exact error reported by
the kernel, so add the error callback for this.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 include/libnetlink.h |  3 ++-
 libnetlink.c         | 20 +++++++++++++++-----
 net.c                |  4 ++--
 sockets.c            |  2 +-
 4 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/include/libnetlink.h b/include/libnetlink.h
index 616a111..92eded4 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -7,7 +7,8 @@ extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int le
 #define parse_rtattr_nested(tb, max, rta) \
 	(parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)))
 extern int do_rtnl_req(int nl, void *req, int size,
-		int (*receive_callback)(struct nlmsghdr *h, void *), void *);
+		int (*receive_callback)(struct nlmsghdr *h, void *),
+		int (*error_callback)(int err, void *), void *);
 
 extern int addattr_l(struct nlmsghdr *n, int maxlen, int type,
 		const void *data, int alen);
diff --git a/libnetlink.c b/libnetlink.c
index f3ed7cc..84ee6eb 100644
--- a/libnetlink.c
+++ b/libnetlink.c
@@ -21,7 +21,8 @@ int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
 	return 0;
 }
 
-static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *), void *arg)
+static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *), 
+		int (*err_cb)(int, void *), void *arg)
 {
 	struct nlmsghdr *hdr;
 
@@ -50,8 +51,7 @@ static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *
 			if (err->error == 0)
 				return 0;
 
-			pr_warn("ERROR %d reported by netlink\n", err->error);
-			return err->error;
+			return err_cb(err->error, arg);
 		}
 		if (cb(hdr, arg))
 			return -1;
@@ -60,8 +60,15 @@ static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *
 	return 1;
 }
 
+static int rtnl_return_err(int err, void *arg)
+{
+	pr_warn("ERROR %d reported by netlink\n", err);
+	return err;
+}
+
 int do_rtnl_req(int nl, void *req, int size,
-		int (*receive_callback)(struct nlmsghdr *h, void *), void *arg)
+		int (*receive_callback)(struct nlmsghdr *h, void *),
+		int (*error_callback)(int err, void *), void *arg)
 {
 	struct msghdr msg;
 	struct sockaddr_nl nladdr;
@@ -69,6 +76,9 @@ int do_rtnl_req(int nl, void *req, int size,
 	static char buf[4096];
 	int err;
 
+	if (!error_callback)
+		error_callback = rtnl_return_err;
+
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_name	= &nladdr;
 	msg.msg_namelen	= sizeof(nladdr);
@@ -111,7 +121,7 @@ int do_rtnl_req(int nl, void *req, int size,
 		if (err == 0)
 			break;
 
-		err = nlmsg_receive(buf, err, receive_callback, arg);
+		err = nlmsg_receive(buf, err, receive_callback, error_callback, arg);
 		if (err < 0)
 			goto err;
 		if (err == 0)
diff --git a/net.c b/net.c
index 23ef597..015aeda 100644
--- a/net.c
+++ b/net.c
@@ -234,7 +234,7 @@ static int dump_links(struct cr_imgset *fds)
 	req.nlh.nlmsg_seq = CR_NLMSG_SEQ;
 	req.g.rtgen_family = AF_PACKET;
 
-	ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, fds);
+	ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, NULL, fds);
 	close(sk);
 out:
 	return ret;
@@ -297,7 +297,7 @@ static int do_rtm_link_req(int msg_type, NetDeviceEntry *nde, int nlsk,
 		linkinfo->rta_len = (void *)NLMSG_TAIL(&req.h) - (void *)linkinfo;
 	}
 
-	return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL);
+	return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL, NULL);
 }
 
 int restore_link_parms(NetDeviceEntry *nde, int nlsk)
diff --git a/sockets.c b/sockets.c
index 6c71503..dd0ff4f 100644
--- a/sockets.c
+++ b/sockets.c
@@ -538,7 +538,7 @@ static int do_collect_req(int nl, struct sock_diag_req *req, int size,
 {
 	int tmp;
 
-	tmp = do_rtnl_req(nl, req, size, receive_callback, arg);
+	tmp = do_rtnl_req(nl, req, size, receive_callback, NULL, arg);
 
 	if (tmp == 0)
 		set_collect_bit(req->r.n.sdiag_family, req->r.n.sdiag_protocol);
-- 
1.8.4.2




More information about the CRIU mailing list