Skip to content

Commit d105f01

Browse files
committed
rpc/log: return first error always
Use shared first error buffer to return correct first error in rpc. Fixes: #338 Signed-off-by: Ivan Pravdin <ipravdin.official@gmail.com>
1 parent 69f990d commit d105f01

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

criu/cr-service.c

+23-1
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,11 @@ static int check(int sk, CriuOpts *req)
895895

896896
resp.type = CRIU_REQ_TYPE__CHECK;
897897

898+
if (log_keep_err()) {
899+
pr_perror("Can't tune log");
900+
goto out;
901+
}
902+
898903
pid = fork();
899904
if (pid < 0) {
900905
pr_perror("Can't fork");
@@ -919,6 +924,7 @@ static int check(int sk, CriuOpts *req)
919924

920925
resp.success = true;
921926
out:
927+
set_resp_err(&resp);
922928
return send_criu_msg(sk, &resp);
923929
}
924930

@@ -927,6 +933,11 @@ static int pre_dump_using_req(int sk, CriuOpts *req, bool single)
927933
int pid, status;
928934
bool success = false;
929935

936+
if (log_keep_err()) {
937+
pr_perror("Can't tune log");
938+
goto out;
939+
}
940+
930941
pid = fork();
931942
if (pid < 0) {
932943
pr_perror("Can't fork");
@@ -1005,6 +1016,11 @@ static int start_page_server_req(int sk, CriuOpts *req, bool daemon_mode)
10051016
CriuPageServerInfo ps = CRIU_PAGE_SERVER_INFO__INIT;
10061017
struct ps_info info;
10071018

1019+
if (log_keep_err()) {
1020+
pr_perror("Can't tune log");
1021+
goto out;
1022+
}
1023+
10081024
if (pipe(start_pipe)) {
10091025
pr_perror("No start pipe");
10101026
goto out;
@@ -1078,6 +1094,7 @@ static int start_page_server_req(int sk, CriuOpts *req, bool daemon_mode)
10781094
out:
10791095
resp.type = CRIU_REQ_TYPE__PAGE_SERVER;
10801096
resp.success = success;
1097+
set_resp_err(&resp);
10811098
return send_criu_msg(sk, &resp);
10821099
}
10831100

@@ -1252,6 +1269,11 @@ static int handle_cpuinfo(int sk, CriuReq *msg)
12521269
bool success = false;
12531270
int pid, status;
12541271

1272+
if (log_keep_err()) {
1273+
pr_perror("Can't tune log");
1274+
goto out;
1275+
}
1276+
12551277
pid = fork();
12561278
if (pid < 0) {
12571279
pr_perror("Can't fork");
@@ -1301,7 +1323,7 @@ static int handle_cpuinfo(int sk, CriuReq *msg)
13011323
out:
13021324
resp.type = msg->type;
13031325
resp.success = success;
1304-
1326+
set_resp_err(&resp);
13051327
return send_criu_msg(sk, &resp);
13061328
}
13071329

criu/log.c

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <sys/time.h>
1111
#include <sys/resource.h>
1212
#include <sys/utsname.h>
13+
#include <sys/mman.h>
1314

1415
#include <fcntl.h>
1516

@@ -114,6 +115,9 @@ static struct str_and_lock *first_err;
114115

115116
int log_keep_err(void)
116117
{
118+
if (first_err)
119+
return 0;
120+
117121
first_err = shmalloc(sizeof(struct str_and_lock));
118122
if (first_err == NULL)
119123
return -1;

test/others/rpc/errno.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def recv_resp(self):
4040
resp.ParseFromString(self.s.recv(self._MAX_MSG_SIZE))
4141
return resp
4242

43-
def check_resp(self, resp, typ, err):
43+
def check_resp(self, resp, typ, err, errmsg = None):
4444
if resp.type != typ:
4545
raise Exception('Unexpected response type ' + str(resp.type))
4646

@@ -49,6 +49,9 @@ def check_resp(self, resp, typ, err):
4949

5050
if err and resp.cr_errno != err:
5151
raise Exception('Unexpected cr_errno ' + str(resp.cr_errno))
52+
53+
if errmsg and errmsg not in resp.cr_errmsg:
54+
raise Exception('Unexpected cr_msg \'' + str(resp.cr_errmsg) + '\'')
5255

5356
def no_process(self):
5457
print('Try to dump unexisting process')
@@ -131,12 +134,29 @@ def bad_request(self):
131134
self.check_resp(resp, rpc.EMPTY, None)
132135

133136
print('Success')
137+
138+
def child_first_err(self):
139+
print('Receive correct first error message')
140+
141+
req = self.get_base_req()
142+
req.type = rpc.CHECK
143+
144+
# mntns_compat_mode options is only allowed on restore
145+
req.opts.mntns_compat_mode = True
146+
147+
self.send_req(req)
148+
resp = self.recv_resp()
149+
150+
self.check_resp(resp, rpc.CHECK, None, "Option --mntns-compat-mode is only valid on restore\n")
151+
152+
print('Success')
134153

135154
def run(self):
136155
self.no_process()
137156
self.process_exists()
138157
self.bad_options()
139158
self.bad_request()
159+
self.child_first_err()
140160

141161

142162
t = test()

0 commit comments

Comments
 (0)