mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
sock: Handle rcvlowat and priority options
And write a test for them. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -7,4 +7,7 @@ message sk_opts_entry {
|
||||
required uint64 so_rcv_tmo_sec = 5;
|
||||
required uint64 so_rcv_tmo_usec = 6;
|
||||
optional bool reuseaddr = 7;
|
||||
|
||||
optional uint32 so_priority = 8;
|
||||
optional uint32 so_rcvlowat = 9;
|
||||
}
|
||||
|
14
sockets.c
14
sockets.c
@@ -78,6 +78,14 @@ int restore_socket_opts(int sk, SkOptsEntry *soe)
|
||||
pr_info("%d restore sndbuf %d rcv buf %d\n", sk, soe->so_sndbuf, soe->so_rcvbuf);
|
||||
ret |= restore_opt(sk, SOL_SOCKET, SO_SNDBUFFORCE, &soe->so_sndbuf);
|
||||
ret |= restore_opt(sk, SOL_SOCKET, SO_RCVBUFFORCE, &soe->so_rcvbuf);
|
||||
if (soe->has_so_priority) {
|
||||
pr_debug("\trestore priority %d for socket\n", soe->so_priority);
|
||||
ret |= restore_opt(sk, SOL_SOCKET, SO_PRIORITY, &soe->so_priority);
|
||||
}
|
||||
if (soe->has_so_rcvlowat) {
|
||||
pr_debug("\trestore rcvlowat %d for socket\n", soe->so_rcvlowat);
|
||||
ret |= restore_opt(sk, SOL_SOCKET, SO_RCVLOWAT, &soe->so_rcvlowat);
|
||||
}
|
||||
|
||||
tv.tv_sec = soe->so_snd_tmo_sec;
|
||||
tv.tv_usec = soe->so_snd_tmo_usec;
|
||||
@@ -117,6 +125,10 @@ int dump_socket_opts(int sk, SkOptsEntry *soe)
|
||||
|
||||
ret |= dump_opt(sk, SOL_SOCKET, SO_SNDBUF, &soe->so_sndbuf);
|
||||
ret |= dump_opt(sk, SOL_SOCKET, SO_RCVBUF, &soe->so_rcvbuf);
|
||||
soe->has_so_priority = true;
|
||||
ret |= dump_opt(sk, SOL_SOCKET, SO_PRIORITY, &soe->so_priority);
|
||||
soe->has_so_rcvlowat = true;
|
||||
ret |= dump_opt(sk, SOL_SOCKET, SO_RCVLOWAT, &soe->so_rcvlowat);
|
||||
|
||||
ret |= dump_opt(sk, SOL_SOCKET, SO_SNDTIMEO, &tv);
|
||||
soe->so_snd_tmo_sec = tv.tv_sec;
|
||||
@@ -352,6 +364,8 @@ void show_socket_opts(SkOptsEntry *soe)
|
||||
pr_msg("rcvbuf: %u ", soe->so_rcvbuf);
|
||||
pr_msg("sndtmo: %lu.%lu ", soe->so_snd_tmo_sec, soe->so_snd_tmo_usec);
|
||||
pr_msg("rcvtmo: %lu.%lu ", soe->so_rcv_tmo_sec, soe->so_rcv_tmo_usec);
|
||||
pr_msg("prio: %u ", soe->so_priority);
|
||||
pr_msg("rlowat: %u ", soe->so_rcvlowat);
|
||||
|
||||
pr_msg("\n");
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ streaming/pipe_loop00
|
||||
streaming/pipe_shared00
|
||||
transition/file_read
|
||||
static/sockets00
|
||||
static/sock_opts00
|
||||
static/sockets_spair
|
||||
static/sockets_dgram
|
||||
static/socket_queues
|
||||
|
@@ -42,6 +42,7 @@ TST_NOFILE = \
|
||||
socket_queues \
|
||||
socket_queues02 \
|
||||
socket-tcp \
|
||||
sock_opts00 \
|
||||
ipc_namespace \
|
||||
selfexe00 \
|
||||
sem \
|
||||
|
86
test/zdtm/live/static/sock_opts00.c
Normal file
86
test/zdtm/live/static/sock_opts00.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "zdtmtst.h"
|
||||
|
||||
const char *test_doc = "Check various socket options to work";
|
||||
const char *test_author = "Pavel Emelyanov <xemul@parallels.com>";
|
||||
|
||||
#define TEST_PORT 59687
|
||||
#define TEST_ADDR INADDR_ANY
|
||||
|
||||
#define NOPTS 2
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
int sock, ret = 0, vname[NOPTS], val[NOPTS], rval, i;
|
||||
socklen_t len = sizeof(int);
|
||||
|
||||
vname[0] = SO_PRIORITY;
|
||||
vname[1] = SO_RCVLOWAT;
|
||||
|
||||
test_init(argc, argv);
|
||||
|
||||
sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
err("can't create socket: %m");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < NOPTS; i++) {
|
||||
ret = getsockopt(sock, SOL_SOCKET, vname[i], &val[i], &len);
|
||||
if (ret) {
|
||||
err("can't get option %d", i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
val[i]++;
|
||||
|
||||
ret = setsockopt(sock, SOL_SOCKET, vname[i], &val[i], len);
|
||||
if (ret) {
|
||||
err("can't set option %d", i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = getsockopt(sock, SOL_SOCKET, vname[i], &rval, &len);
|
||||
if (ret) {
|
||||
err("can't get option %d 2", i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rval != val[i]) {
|
||||
if (rval + 1 == val[i]) {
|
||||
err("can't reset option %d want %d have %d", i,
|
||||
val[i], rval);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* kernel tuned things up on set */
|
||||
val[i] = rval;
|
||||
}
|
||||
}
|
||||
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
|
||||
for (i = 0; i < NOPTS; i++) {
|
||||
ret = getsockopt(sock, SOL_SOCKET, vname[i], &rval, &len);
|
||||
if (ret) {
|
||||
err("can't get option %d again", i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (val[i] != rval) {
|
||||
fail("option %d changed", i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
pass();
|
||||
close(sock);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user