Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
criu
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhul
criu
Commits
f3253a40
Commit
f3253a40
authored
Jan 17, 2012
by
Stanislav Kinsbursky
Committed by
Cyrill Gorcunov
Jan 18, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
checkpoint: IPv4 listening sockets dumping support
parent
654216c1
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
307 additions
and
0 deletions
+307
-0
crtools.c
crtools.c
+7
-0
crtools.h
include/crtools.h
+2
-0
image.h
include/image.h
+14
-0
inet_diag.h
include/inet_diag.h
+135
-0
sockets.c
sockets.c
+149
-0
No files found.
crtools.c
View file @
f3253a40
...
...
@@ -85,6 +85,13 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
.
fmt
=
FMT_FNAME_UNIXSK
,
.
magic
=
UNIXSK_MAGIC
,
},
/* info about inet sockets */
[
CR_FD_INETSK
]
=
{
.
fmt
=
FMT_FNAME_INETSK
,
.
magic
=
INETSK_MAGIC
,
},
};
static
struct
cr_fdset
*
alloc_cr_fdset
(
void
)
...
...
include/crtools.h
View file @
f3253a40
...
...
@@ -24,6 +24,7 @@ enum {
CR_FD_SHMEM
,
CR_FD_SIGACT
,
CR_FD_UNIXSK
,
CR_FD_INETSK
,
CR_FD_MAX
};
...
...
@@ -60,6 +61,7 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
#define FMT_FNAME_VMAS "vmas-%d.img"
#define FMT_FNAME_SIGACTS "sigacts-%d.img"
#define FMT_FNAME_UNIXSK "unixsk-%d.img"
#define FMT_FNAME_INETSK "inetsk-%d.img"
extern
int
get_image_path
(
char
*
path
,
int
size
,
const
char
*
fmt
,
int
pid
);
...
...
include/image.h
View file @
f3253a40
...
...
@@ -13,6 +13,7 @@
#define PIPES_MAGIC 0x05055050
#define SIGACT_MAGIC 0x60606060
#define UNIXSK_MAGIC 0x07070707
#define INETSK_MAGIC 0x08080808
#define FDINFO_FD 1
#define FDINFO_MAP 2
...
...
@@ -69,6 +70,19 @@ struct unix_sk_entry {
u8
name
[
0
];
}
__packed
;
struct
inet_sk_entry
{
u32
fd
;
u32
id
;
u8
family
;
u8
type
;
u8
proto
;
u8
state
;
u16
src_port
;
u8
pad
[
2
];
u32
backlog
;
u32
src_addr
[
4
];
}
__packed
;
struct
vma_entry
{
u64
start
;
u64
end
;
...
...
include/inet_diag.h
0 → 100644
View file @
f3253a40
#ifndef _INET_DIAG_H_
#define _INET_DIAG_H_ 1
#include <linux/types.h>
/* Just some random number */
#define TCPDIAG_GETSOCK 18
#define DCCPDIAG_GETSOCK 19
#define INET_DIAG_GETSOCK_MAX 24
/* Socket identity */
struct
inet_diag_sockid
{
__be16
idiag_sport
;
__be16
idiag_dport
;
__be32
idiag_src
[
4
];
__be32
idiag_dst
[
4
];
__u32
idiag_if
;
__u32
idiag_cookie
[
2
];
#define INET_DIAG_NOCOOKIE (~0U)
};
/* Request structure */
struct
inet_diag_req_compat
{
__u8
idiag_family
;
/* Family of addresses. */
__u8
idiag_src_len
;
__u8
idiag_dst_len
;
__u8
idiag_ext
;
/* Query extended information */
struct
inet_diag_sockid
id
;
__u32
idiag_states
;
/* States to dump */
__u32
idiag_dbs
;
/* Tables to dump (NI) */
};
struct
inet_diag_req
{
__u8
sdiag_family
;
__u8
sdiag_protocol
;
__u8
idiag_ext
;
__u8
pad
;
__u32
idiag_states
;
struct
inet_diag_sockid
id
;
};
enum
{
INET_DIAG_REQ_NONE
,
INET_DIAG_REQ_BYTECODE
,
};
#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE
/* Bytecode is sequence of 4 byte commands followed by variable arguments.
* All the commands identified by "code" are conditional jumps forward:
* to offset cc+"yes" or to offset cc+"no". "yes" is supposed to be
* length of the command and its arguments.
*/
struct
inet_diag_bc_op
{
unsigned
char
code
;
unsigned
char
yes
;
unsigned
short
no
;
};
enum
{
INET_DIAG_BC_NOP
,
INET_DIAG_BC_JMP
,
INET_DIAG_BC_S_GE
,
INET_DIAG_BC_S_LE
,
INET_DIAG_BC_D_GE
,
INET_DIAG_BC_D_LE
,
INET_DIAG_BC_AUTO
,
INET_DIAG_BC_S_COND
,
INET_DIAG_BC_D_COND
,
};
struct
inet_diag_hostcond
{
__u8
family
;
__u8
prefix_len
;
int
port
;
__be32
addr
[
0
];
};
/* Base info structure. It contains socket identity (addrs/ports/cookie)
* and, alas, the information shown by netstat. */
struct
inet_diag_msg
{
__u8
idiag_family
;
__u8
idiag_state
;
__u8
idiag_timer
;
__u8
idiag_retrans
;
struct
inet_diag_sockid
id
;
__u32
idiag_expires
;
__u32
idiag_rqueue
;
__u32
idiag_wqueue
;
__u32
idiag_uid
;
__u32
idiag_inode
;
};
/* Extensions */
enum
{
INET_DIAG_NONE
,
INET_DIAG_MEMINFO
,
INET_DIAG_INFO
,
INET_DIAG_VEGASINFO
,
INET_DIAG_CONG
,
INET_DIAG_TOS
,
INET_DIAG_TCLASS
,
INET_DIAG_SKMEMINFO
,
};
#define INET_DIAG_MAX INET_DIAG_SKMEMINFO
/* INET_DIAG_MEM */
struct
inet_diag_meminfo
{
__u32
idiag_rmem
;
__u32
idiag_wmem
;
__u32
idiag_fmem
;
__u32
idiag_tmem
;
};
/* INET_DIAG_VEGASINFO */
struct
tcpvegas_info
{
__u32
tcpv_enabled
;
__u32
tcpv_rttcnt
;
__u32
tcpv_rtt
;
__u32
tcpv_minrtt
;
};
#endif
/* _INET_DIAG_H_ */
sockets.c
View file @
f3253a40
...
...
@@ -11,6 +11,7 @@
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <arpa/inet.h>
#include "types.h"
#include "libnetlink.h"
...
...
@@ -19,6 +20,7 @@
#include "image.h"
#include "crtools.h"
#include "util.h"
#include "inet_diag.h"
static
char
buf
[
4096
];
...
...
@@ -52,6 +54,19 @@ struct unix_sk_desc {
unsigned
int
*
icons
;
};
#define INET_ADDR_LEN 40
struct
inet_sk_desc
{
struct
socket_desc
sd
;
unsigned
int
type
;
unsigned
int
proto
;
unsigned
int
src_port
;
unsigned
int
state
;
unsigned
int
rqlen
;
unsigned
int
wqlen
;
unsigned
int
src_addr
[
4
];
};
#define SK_HASH_SIZE 32
static
struct
socket_desc
*
sockets
[
SK_HASH_SIZE
];
...
...
@@ -78,6 +93,36 @@ static int sk_collect_one(int ino, int family, struct socket_desc *d)
return
0
;
}
static
void
show_one_inet
(
char
*
act
,
struct
inet_sk_desc
*
sk
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
if
(
inet_ntop
(
AF_INET
,
(
void
*
)
sk
->
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_err
(
"Failed to translate address: %d
\n
"
,
errno
);
}
dprintk
(
"
\t
%s: ino %d family %d type %d port %d "
"state %d src_addr %s
\n
"
,
act
,
sk
->
sd
.
ino
,
sk
->
sd
.
family
,
sk
->
type
,
sk
->
src_port
,
sk
->
state
,
src_addr
);
}
static
void
show_one_inet_img
(
char
*
act
,
struct
inet_sk_entry
*
e
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
if
(
inet_ntop
(
AF_INET
,
(
void
*
)
e
->
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_err
(
"Failed to translate address: %d
\n
"
,
errno
);
}
dprintk
(
"
\t
%s: fd %d family %d type %d proto %d port %d "
"state %d src_addr %d bytes
\n
"
,
act
,
e
->
fd
,
e
->
family
,
e
->
type
,
e
->
proto
,
e
->
src_port
,
e
->
state
,
src_addr
);
}
static
void
show_one_unix
(
char
*
act
,
struct
unix_sk_desc
*
sk
)
{
dprintk
(
"
\t
%s: ino %d type %d state %d name %s
\n
"
,
...
...
@@ -90,6 +135,69 @@ static void show_one_unix_img(char *act, struct unix_sk_entry *e)
act
,
e
->
fd
,
e
->
type
,
e
->
state
,
e
->
namelen
);
}
static
int
can_dump_inet_sk
(
struct
inet_sk_desc
*
sk
)
{
if
(
sk
->
sd
.
family
!=
AF_INET
)
{
pr_err
(
"Only IPv4 sockets for now
\n
"
);
return
0
;
}
if
(
sk
->
type
!=
SOCK_STREAM
)
{
pr_err
(
"Only stream inet sockets for now
\n
"
);
return
0
;
}
switch
(
sk
->
state
)
{
case
TCP_LISTEN
:
if
(
sk
->
rqlen
!=
0
)
{
/*
* Currently the ICONS nla reports the conn
* requests for listen sockets. Need to pick
* those up and fix the connect job respectively
*/
pr_err
(
"In-flight connection (l)
\n
"
);
return
0
;
}
break
;
default:
pr_err
(
"Unknown state %d
\n
"
,
sk
->
state
);
return
0
;
}
return
1
;
}
static
int
dump_one_inet
(
struct
socket_desc
*
_sk
,
int
fd
,
struct
cr_fdset
*
cr_fdset
)
{
struct
inet_sk_desc
*
sk
=
(
struct
inet_sk_desc
*
)
_sk
;
struct
inet_sk_entry
ie
;
if
(
!
can_dump_inet_sk
(
sk
))
goto
err
;
memset
(
&
ie
,
0
,
sizeof
(
ie
));
ie
.
fd
=
fd
;
ie
.
id
=
sk
->
sd
.
ino
;
ie
.
family
=
sk
->
sd
.
family
;
ie
.
type
=
sk
->
type
;
ie
.
proto
=
sk
->
proto
;
ie
.
state
=
sk
->
state
;
ie
.
src_port
=
sk
->
src_port
;
ie
.
backlog
=
sk
->
wqlen
;
memcpy
(
ie
.
src_addr
,
sk
->
src_addr
,
sizeof
(
u32
)
*
4
);
write_ptr_safe
(
cr_fdset
->
fds
[
CR_FD_INETSK
],
&
ie
,
err
);
pr_info
(
"Dumping inet socket at %d
\n
"
,
fd
);
show_one_inet
(
"Dumping"
,
sk
);
show_one_inet_img
(
"Dumped"
,
&
ie
);
return
0
;
err:
return
-
1
;
}
static
int
can_dump_unix_sk
(
struct
unix_sk_desc
*
sk
)
{
if
(
sk
->
type
!=
SOCK_STREAM
&&
...
...
@@ -209,6 +317,8 @@ int try_dump_socket(pid_t pid, int fd, struct cr_fdset *cr_fdset)
switch
(
sk
->
family
)
{
case
AF_UNIX
:
return
dump_one_unix
(
sk
,
fd
,
cr_fdset
);
case
AF_INET
:
return
dump_one_inet
(
sk
,
fd
,
cr_fdset
);
default:
pr_err
(
"BUG! Unknown socket collected
\n
"
);
break
;
...
...
@@ -217,6 +327,36 @@ int try_dump_socket(pid_t pid, int fd, struct cr_fdset *cr_fdset)
return
-
1
;
}
static
int
inet_tcp_collect_one
(
struct
inet_diag_msg
*
m
,
struct
rtattr
**
tb
)
{
struct
inet_sk_desc
*
d
;
d
=
xzalloc
(
sizeof
(
*
d
));
if
(
!
d
)
return
-
1
;
d
->
type
=
SOCK_STREAM
;
d
->
proto
=
IPPROTO_TCP
;
d
->
src_port
=
ntohs
(
m
->
id
.
idiag_sport
);
d
->
state
=
m
->
idiag_state
;
d
->
rqlen
=
m
->
idiag_rqueue
;
d
->
wqlen
=
m
->
idiag_wqueue
;
memcpy
(
d
->
src_addr
,
m
->
id
.
idiag_src
,
sizeof
(
u32
)
*
4
);
return
sk_collect_one
(
m
->
idiag_inode
,
AF_INET
,
&
d
->
sd
);
}
static
int
inet_tcp_receive_one
(
struct
nlmsghdr
*
h
)
{
struct
inet_diag_msg
*
m
=
NLMSG_DATA
(
h
);
struct
rtattr
*
tb
[
INET_DIAG_MAX
+
1
];
parse_rtattr
(
tb
,
INET_DIAG_MAX
,
(
struct
rtattr
*
)(
m
+
1
),
h
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
m
)));
return
inet_tcp_collect_one
(
m
,
tb
);
}
static
int
unix_collect_one
(
struct
unix_diag_msg
*
m
,
struct
rtattr
**
tb
)
{
struct
unix_sk_desc
*
d
,
**
h
;
...
...
@@ -391,6 +531,7 @@ int collect_sockets(void)
struct
nlmsghdr
hdr
;
union
{
struct
unix_diag_req
u
;
struct
inet_diag_req
i
;
}
r
;
}
req
;
...
...
@@ -416,6 +557,14 @@ int collect_sockets(void)
if
(
err
)
goto
out
;
/* Collect IPv4 TCP sockets */
req
.
r
.
i
.
sdiag_family
=
AF_INET
;
req
.
r
.
i
.
sdiag_protocol
=
IPPROTO_TCP
;
req
.
r
.
i
.
idiag_ext
=
1
<<
(
INET_DIAG_INFO
-
1
);
/* Only listening sockets supported yet */
req
.
r
.
i
.
idiag_states
=
1
<<
TCP_LISTEN
;
err
=
collect_sockets_nl
(
nl
,
&
req
,
sizeof
(
req
),
inet_tcp_receive_one
);
out:
close
(
nl
);
return
err
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment