[CRIU] [PATCH 14/18] sk-unix: Collect deleted identical addresses in the queues
Cyrill Gorcunov
gorcunov at openvz.org
Wed Apr 12 06:58:34 PDT 2017
We will need to resolve them to be able to restore.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
criu/sk-unix.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index 5acef298d109..c7aa3099c00c 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -28,6 +28,7 @@
#include "pstree.h"
#include "external.h"
#include "crtools.h"
+#include "rst-malloc.h"
#include "protobuf.h"
#include "images/sk-unix.pb-c.h"
@@ -88,6 +89,7 @@ struct unix_sk_desc {
};
static LIST_HEAD(unix_sockets);
+static LIST_HEAD(unix_ghost_addr);
struct unix_sk_listen_icon {
unsigned int peer_ino;
@@ -97,6 +99,13 @@ struct unix_sk_listen_icon {
#define SK_HASH_SIZE 32
+typedef struct {
+ struct list_head list;
+ struct list_head children;
+ char *name;
+ size_t namelen;
+} ghost_addr_t;
+
static struct unix_sk_listen_icon *unix_listen_icons[SK_HASH_SIZE];
static struct unix_sk_listen_icon *lookup_unix_listen_icons(int peer_ino)
@@ -110,6 +119,20 @@ static struct unix_sk_listen_icon *lookup_unix_listen_icons(int peer_ino)
return NULL;
}
+static ghost_addr_t *lookup_ghost_addr(void *name, size_t namelen)
+{
+ ghost_addr_t *ga;
+
+ list_for_each_entry(ga, &unix_ghost_addr, list) {
+ if (ga->namelen != namelen ||
+ memcmp(ga->name, name, namelen))
+ continue;
+ return ga;
+ }
+
+ return NULL;
+}
+
static void show_one_unix(char *act, const struct unix_sk_desc *sk)
{
pr_debug("\t%s: ino %#x peer_ino %#x family %4d type %4d state %2d name %s\n",
@@ -788,6 +811,8 @@ struct unix_sk_info {
struct list_head connected; /* List of sockets, connected to me */
struct list_head node; /* To link in peer's connected list */
+ struct list_head ghost_addr_node;
+
/*
* For DGRAM sockets with queues, we should only restore the queue
* once although it may be open by more than one tid. This is the peer
@@ -800,6 +825,9 @@ struct unix_sk_info {
#define USK_PAIR_MASTER (1 << 0)
#define USK_PAIR_SLAVE (1 << 1)
+#define USK_GHOST_NAME (1 << 2)
+#define USK_GHOST_WAIT (1 << 3)
+#define USK_ADDR_RDY (1 << 4)
static struct unix_sk_info *find_unix_sk_by_ino(int ino)
{
@@ -1378,6 +1406,8 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i)
ui->ue = pb_msg(base, UnixSkEntry);
ui->name_dir = (void *)ui->ue->name_dir;
+ INIT_LIST_HEAD(&ui->ghost_addr_node);
+
if (add_post_prepare_cb_once(resolve_unix_peers, NULL))
return -1;
@@ -1390,6 +1420,26 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i)
ui->name = (void *)ui->ue->name.data;
unlink_stale(ui);
+ if (ui->ue->has_deleted && ui->ue->deleted &&
+ ui->ue->type == SOCK_DGRAM) {
+ ghost_addr_t *ga;
+
+ ga = lookup_ghost_addr(ui->name, ui->ue->name.len);
+ if (!ga) {
+ ga = shmalloc(sizeof(*ga));
+ if (!ga)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&ga->children);
+
+ ga->name = (void *)ui->name;
+ ga->namelen = ui->ue->name.len;
+
+ list_add_tail(&ga->list, &unix_ghost_addr);
+ }
+
+ list_add_tail(&ui->ghost_addr_node, &ga->children);
+ }
} else
ui->name = NULL;
--
2.7.4
More information about the CRIU
mailing list