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
c08eb3dd
Commit
c08eb3dd
authored
Aug 05, 2016
by
Pavel Emelyanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
soccr/tcp: Read queues contents using library
Signed-off-by:
Pavel Emelyanov
<
xemul@virtuozzo.com
>
parent
d98c0ea6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
119 additions
and
105 deletions
+119
-105
sk-tcp.c
criu/sk-tcp.c
+13
-105
soccr.c
soccr/soccr.c
+105
-0
soccr.h
soccr/soccr.h
+1
-0
No files found.
criu/sk-tcp.c
View file @
c08eb3dd
...
...
@@ -157,89 +157,13 @@ void cpt_unlock_tcp_connections(void)
tcp_unlock_one
(
sk
);
}
/*
* TCP queues sequences and their relations to the code below
*
* output queue
* net <----------------------------- sk
* ^ ^ ^ seq >>
* snd_una snd_nxt write_seq
*
* input queue
* net -----------------------------> sk
* << seq ^ ^
* rcv_nxt copied_seq
*
*
* inq_len = rcv_nxt - copied_seq = SIOCINQ
* outq_len = write_seq - snd_una = SIOCOUTQ
* inq_seq = rcv_nxt
* outq_seq = write_seq
*
* On restore kernel moves the option we configure with setsockopt,
* thus we should advance them on the _len value in restore_tcp_seqs.
*
*/
static
int
tcp_stream_get_queue
(
int
sk
,
int
queue_id
,
u32
*
seq
,
u32
len
,
char
**
bufp
)
{
int
ret
,
aux
;
socklen_t
auxl
;
char
*
buf
;
pr_debug
(
"
\t
Set repair queue %d
\n
"
,
queue_id
);
aux
=
queue_id
;
auxl
=
sizeof
(
aux
);
ret
=
setsockopt
(
sk
,
SOL_TCP
,
TCP_REPAIR_QUEUE
,
&
aux
,
auxl
);
if
(
ret
<
0
)
goto
err_sopt
;
pr_debug
(
"
\t
Get queue seq
\n
"
);
auxl
=
sizeof
(
*
seq
);
ret
=
getsockopt
(
sk
,
SOL_TCP
,
TCP_QUEUE_SEQ
,
seq
,
&
auxl
);
if
(
ret
<
0
)
goto
err_sopt
;
pr_info
(
"
\t
`- seq %u len %u
\n
"
,
*
seq
,
len
);
if
(
len
)
{
/*
* Try to grab one byte more from the queue to
* make sure there are len bytes for real
*/
buf
=
xmalloc
(
len
+
1
);
if
(
!
buf
)
goto
err_buf
;
pr_debug
(
"
\t
Reading queue (%d bytes)
\n
"
,
len
);
ret
=
recv
(
sk
,
buf
,
len
+
1
,
MSG_PEEK
|
MSG_DONTWAIT
);
if
(
ret
!=
len
)
goto
err_recv
;
}
else
buf
=
NULL
;
*
bufp
=
buf
;
return
0
;
err_sopt:
pr_perror
(
"
\t
sockopt failed"
);
err_buf:
return
-
1
;
err_recv:
pr_perror
(
"
\t
recv failed (%d, want %d, errno %d)"
,
ret
,
len
,
errno
);
xfree
(
buf
);
goto
err_buf
;
}
static
int
dump_tcp_conn_state
(
struct
inet_sk_desc
*
sk
)
{
struct
libsoccr_sk
*
socr
=
sk
->
priv
;
int
ret
,
aux
;
struct
cr_img
*
img
;
TcpStreamEntry
tse
=
TCP_STREAM_ENTRY__INIT
;
char
*
in_buf
,
*
out_
buf
;
char
*
buf
;
struct
libsoccr_sk_data
data
;
ret
=
libsoccr_get_sk_data
(
socr
,
&
data
,
sizeof
(
data
));
...
...
@@ -252,7 +176,9 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk)
}
tse
.
inq_len
=
data
.
inq_len
;
tse
.
inq_seq
=
data
.
inq_seq
;
tse
.
outq_len
=
data
.
outq_len
;
tse
.
outq_seq
=
data
.
outq_seq
;
tse
.
unsq_len
=
data
.
unsq_len
;
tse
.
has_unsq_len
=
true
;
tse
.
mss_clamp
=
data
.
mss_clamp
;
...
...
@@ -280,26 +206,6 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk)
tse
.
rcv_wup
=
data
.
rcv_wup
;
}
/*
* Read queue
*/
pr_info
(
"Reading inq for socket
\n
"
);
ret
=
tcp_stream_get_queue
(
sk
->
rfd
,
TCP_RECV_QUEUE
,
&
tse
.
inq_seq
,
tse
.
inq_len
,
&
in_buf
);
if
(
ret
<
0
)
goto
err_in
;
/*
* Write queue
*/
pr_info
(
"Reading outq for socket
\n
"
);
ret
=
tcp_stream_get_queue
(
sk
->
rfd
,
TCP_SEND_QUEUE
,
&
tse
.
outq_seq
,
tse
.
outq_len
,
&
out_buf
);
if
(
ret
<
0
)
goto
err_out
;
/*
* TCP socket options
*/
...
...
@@ -332,16 +238,22 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk)
if
(
ret
<
0
)
goto
err_iw
;
if
(
in_buf
)
{
ret
=
write_img_buf
(
img
,
in_buf
,
tse
.
inq_len
);
buf
=
libsoccr_get_queue_bytes
(
socr
,
TCP_RECV_QUEUE
,
1
);
if
(
buf
)
{
ret
=
write_img_buf
(
img
,
buf
,
tse
.
inq_len
);
if
(
ret
<
0
)
goto
err_iw
;
xfree
(
buf
);
}
if
(
out_buf
)
{
ret
=
write_img_buf
(
img
,
out_buf
,
tse
.
outq_len
);
buf
=
libsoccr_get_queue_bytes
(
socr
,
TCP_SEND_QUEUE
,
1
);
if
(
buf
)
{
ret
=
write_img_buf
(
img
,
buf
,
tse
.
outq_len
);
if
(
ret
<
0
)
goto
err_iw
;
xfree
(
buf
);
}
pr_info
(
"Done
\n
"
);
...
...
@@ -349,10 +261,6 @@ err_iw:
close_image
(
img
);
err_img:
err_opt:
xfree
(
out_buf
);
err_out:
xfree
(
in_buf
);
err_in:
err_r:
return
ret
;
}
...
...
soccr/soccr.c
View file @
c08eb3dd
...
...
@@ -59,6 +59,8 @@ static void tcp_repair_off(int fd)
struct
libsoccr_sk
{
int
fd
;
char
*
recv_queue
;
char
*
send_queue
;
};
struct
libsoccr_sk
*
libsoccr_pause
(
int
fd
)
...
...
@@ -74,6 +76,8 @@ struct libsoccr_sk *libsoccr_pause(int fd)
return
NULL
;
}
ret
->
recv_queue
=
NULL
;
ret
->
send_queue
=
NULL
;
ret
->
fd
=
fd
;
return
ret
;
}
...
...
@@ -81,6 +85,8 @@ struct libsoccr_sk *libsoccr_pause(int fd)
void
libsoccr_resume
(
struct
libsoccr_sk
*
sk
)
{
tcp_repair_off
(
sk
->
fd
);
free
(
sk
->
send_queue
);
free
(
sk
->
recv_queue
);
free
(
sk
);
}
...
...
@@ -185,6 +191,77 @@ static int get_window(struct libsoccr_sk *sk, struct libsoccr_sk_data *data)
return
0
;
}
/*
* TCP queues sequences and their relations to the code below
*
* output queue
* net <----------------------------- sk
* ^ ^ ^ seq >>
* snd_una snd_nxt write_seq
*
* input queue
* net -----------------------------> sk
* << seq ^ ^
* rcv_nxt copied_seq
*
*
* inq_len = rcv_nxt - copied_seq = SIOCINQ
* outq_len = write_seq - snd_una = SIOCOUTQ
* inq_seq = rcv_nxt
* outq_seq = write_seq
*
* On restore kernel moves the option we configure with setsockopt,
* thus we should advance them on the _len value in restore_tcp_seqs.
*
*/
static
int
get_queue
(
int
sk
,
int
queue_id
,
__u32
*
seq
,
__u32
len
,
char
**
bufp
)
{
int
ret
,
aux
;
socklen_t
auxl
;
char
*
buf
;
aux
=
queue_id
;
auxl
=
sizeof
(
aux
);
ret
=
setsockopt
(
sk
,
SOL_TCP
,
TCP_REPAIR_QUEUE
,
&
aux
,
auxl
);
if
(
ret
<
0
)
goto
err_sopt
;
auxl
=
sizeof
(
*
seq
);
ret
=
getsockopt
(
sk
,
SOL_TCP
,
TCP_QUEUE_SEQ
,
seq
,
&
auxl
);
if
(
ret
<
0
)
goto
err_sopt
;
if
(
len
)
{
/*
* Try to grab one byte more from the queue to
* make sure there are len bytes for real
*/
buf
=
malloc
(
len
+
1
);
if
(
!
buf
)
goto
err_buf
;
ret
=
recv
(
sk
,
buf
,
len
+
1
,
MSG_PEEK
|
MSG_DONTWAIT
);
if
(
ret
!=
len
)
goto
err_recv
;
}
else
buf
=
NULL
;
*
bufp
=
buf
;
return
0
;
err_sopt:
loge
(
"
\t
sockopt failed"
);
err_buf:
return
-
1
;
err_recv:
loge
(
"
\t
recv failed (%d, want %d)"
,
ret
,
len
);
free
(
buf
);
goto
err_buf
;
}
/*
* This is how much data we've had in the initial libsoccr
*/
...
...
@@ -208,5 +285,33 @@ int libsoccr_get_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
if
(
get_window
(
sk
,
data
))
return
-
4
;
if
(
get_queue
(
sk
->
fd
,
TCP_RECV_QUEUE
,
&
data
->
inq_seq
,
data
->
inq_len
,
&
sk
->
recv_queue
))
return
-
4
;
if
(
get_queue
(
sk
->
fd
,
TCP_SEND_QUEUE
,
&
data
->
outq_seq
,
data
->
outq_len
,
&
sk
->
send_queue
))
return
-
5
;
return
sizeof
(
struct
libsoccr_sk_data
);
}
char
*
libsoccr_get_queue_bytes
(
struct
libsoccr_sk
*
sk
,
int
queue_id
,
int
steal
)
{
char
**
p
,
*
ret
;
switch
(
queue_id
)
{
case
TCP_RECV_QUEUE
:
p
=
&
sk
->
recv_queue
;
break
;
case
TCP_SEND_QUEUE
:
p
=
&
sk
->
send_queue
;
break
;
default:
return
NULL
;
}
ret
=
*
p
;
if
(
steal
)
*
p
=
NULL
;
return
ret
;
}
soccr/soccr.h
View file @
c08eb3dd
...
...
@@ -51,5 +51,6 @@ struct libsoccr_sk *libsoccr_pause(int fd);
void
libsoccr_resume
(
struct
libsoccr_sk
*
sk
);
int
libsoccr_get_sk_data
(
struct
libsoccr_sk
*
sk
,
struct
libsoccr_sk_data
*
data
,
unsigned
data_size
);
char
*
libsoccr_get_queue_bytes
(
struct
libsoccr_sk
*
sk
,
int
queue_id
,
int
steal
);
#endif
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