[CRIU] [PATCH 7/8] sockets: restore netlink sockets
Andrey Vagin
avagin at openvz.org
Mon Mar 25 11:28:48 EDT 2013
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 3 ++
include/sockets.h | 2 ++
sk-netlink.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+)
diff --git a/cr-restore.c b/cr-restore.c
index b4a6da2..4d99a9a 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -133,6 +133,9 @@ static int root_prepare_shared(void)
if (collect_packet_sockets())
return -1;
+ if (collect_netlink_sockets())
+ return -1;
+
if (collect_eventfd())
return -1;
diff --git a/include/sockets.h b/include/sockets.h
index 02b0584..a596fa8 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -39,6 +39,8 @@ extern int collect_unix_sockets(void);
extern int fix_external_unix_sockets(void);
extern int resolve_unix_peers(void);
+extern int collect_netlink_sockets(void);
+
extern void show_unixsk(int fd, struct cr_options *o);
extern void show_inetsk(int fd, struct cr_options *o);
extern void show_sk_queues(int fd, struct cr_options *o);
diff --git a/sk-netlink.c b/sk-netlink.c
index e387cc1..f601b71 100644
--- a/sk-netlink.c
+++ b/sk-netlink.c
@@ -162,3 +162,91 @@ int dump_one_netlink(struct fd_parms *p, int lfd, const int fdinfo)
{
return do_dump_gen_file(p, lfd, &netlink_dump_ops, fdinfo);
}
+
+struct netlink_sock_info {
+ NetlinkSkEntry *nse;
+ struct file_desc d;
+};
+
+static int open_netlink_sk(struct file_desc *d)
+{
+ struct netlink_sock_info *nsi;
+ NetlinkSkEntry *nse;
+ struct sockaddr_nl addr;
+ int sk = -1;
+
+ nsi = container_of(d, struct netlink_sock_info, d);
+ nse = nsi->nse;
+
+ pr_info("Opening netlink socket id %#x\n", nse->id);
+
+ sk = socket(PF_NETLINK, SOCK_RAW, nse->protocol);
+ if (sk < 0) {
+ pr_perror("Can't create netlink sock");
+ goto err;
+ }
+
+ if (nse->portid) {
+ memset(&addr, 0, sizeof(addr));
+ addr.nl_family = AF_NETLINK;
+ if (nse->n_groups > 1) {
+ pr_err("Groups above 32 are not supported yet\n");
+ goto err;
+ }
+ if (nse->n_groups)
+ addr.nl_groups = nse->groups[0];
+ addr.nl_pid = nse->portid;
+
+ if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ pr_perror("Can't bind netlink socket");
+ goto err;
+ }
+ }
+
+ if (nse->state == NETLINK_CONNECTED) {
+ addr.nl_family = AF_NETLINK;
+ addr.nl_groups = 1 << (nse->dst_group - 1);
+ addr.nl_pid = nse->dst_portid;
+ if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ pr_perror("Can't connect netlink socket");
+ goto err;
+ }
+ }
+
+ if (rst_file_params(sk, nse->fown, nse->flags))
+ goto err;
+
+ if (restore_socket_opts(sk, nse->opts))
+ goto err;
+
+ return sk;
+err:
+ close(sk);
+ return -1;
+}
+
+static struct file_desc_ops netlink_sock_desc_ops = {
+ .type = FD_TYPES__NETLINKSK,
+ .open = open_netlink_sk,
+};
+
+static int collect_one_netlink_sk(void *o, ProtobufCMessage *base)
+{
+ struct netlink_sock_info *si = o;
+
+ si->nse = pb_msg(base, NetlinkSkEntry);
+ file_desc_add(&si->d, si->nse->id, &netlink_sock_desc_ops);
+
+ return 0;
+}
+
+int collect_netlink_sockets(void)
+{
+ int ret = collect_image(CR_FD_NETLINKSK, PB_NETLINKSK,
+ sizeof(struct netlink_sock_info), collect_one_netlink_sk);
+
+ if (ret < 0 && errno == ENOENT)
+ return 0;
+
+ return ret;
+}
--
1.7.11.7
More information about the CRIU
mailing list