2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-28 04:48:16 +00:00
Mike Rapoport dc4d61f84f compel/test: fix "infect" test compilation errors
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
2017-09-21 01:00:23 +03:00

179 lines
3.6 KiB
C

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <compel/compel.h>
#include "parasite.h"
#define PARASITE_CMD_INC PARASITE_USER_CMDS
#define PARASITE_CMD_DEC PARASITE_USER_CMDS + 1
static void print_vmsg(unsigned int lvl, const char *fmt, va_list parms)
{
printf("\tLC%u: ", lvl);
vprintf(fmt, parms);
}
static int do_infection(int pid)
{
#define err_and_ret(msg) do { fprintf(stderr, msg); return -1; } while (0)
int state;
struct parasite_ctl *ctl;
struct infect_ctx *ictx;
int *arg;
compel_log_init(print_vmsg, COMPEL_LOG_DEBUG);
printf("Stopping task\n");
state = compel_stop_task(pid);
if (state < 0)
err_and_ret("Can't stop task");
printf("Preparing parasite ctl\n");
ctl = compel_prepare(pid);
if (!ctl)
err_and_ret("Can't prepare for infection");
printf("Configuring contexts\n");
/*
* First -- the infection context. Most of the stuff
* is already filled by compel_prepare(), just set the
* log descriptor for parasite side, library cannot
* live w/o it.
*/
ictx = compel_infect_ctx(ctl);
ictx->log_fd = STDERR_FILENO;
parasite_setup_c_header(ctl);
printf("Infecting\n");
if (compel_infect(ctl, 1, sizeof(int)))
err_and_ret("Can't infect victim");
/*
* Now get the area with arguments and run two
* commands one by one.
*/
arg = compel_parasite_args(ctl, int);
printf("Running cmd 1\n");
*arg = 137;
if (compel_rpc_call_sync(PARASITE_CMD_INC, ctl))
err_and_ret("Can't run parasite command 1");
printf("Running cmd 2\n");
*arg = 404;
if (compel_rpc_call_sync(PARASITE_CMD_DEC, ctl))
err_and_ret("Can't run parasite command 2");
/*
* Done. Cure and resume the task.
*/
printf("Curing\n");
if (compel_cure(ctl))
err_and_ret("Can't cure victim");
if (compel_resume_task(pid, state, state))
err_and_ret("Can't unseize task");
printf("Done\n");
return 0;
}
static inline int chk(int fd, int val)
{
int v = 0;
if (read(fd, &v, sizeof(v)) != sizeof(v))
return 0;
printf("%d, want %d\n", v, val);
return v == val;
}
int main(int argc, char **argv)
{
int p_in[2], p_out[2], p_err[2], pid, i, pass = 1;
/*
* Prepare IO-s and fork the victim binary
*/
if (pipe(p_in) || pipe(p_out) || pipe(p_err)) {
perror("Can't make pipe");
return -1;
}
pid = vfork();
if (pid == 0) {
close(p_in[1]); dup2(p_in[0], 0); close(p_in[0]);
close(p_out[0]); dup2(p_out[1], 1); close(p_out[1]);
close(p_err[0]); dup2(p_err[1], 2); close(p_err[1]);
execl("./victim", "victim", NULL);
exit(1);
}
close(p_in[0]); close(p_out[1]); close(p_err[1]);
/*
* Tell the little guy some numbers
*/
i = 1;
if (write(p_in[1], &i, sizeof(i)) != sizeof(i))
return 1;
i = 42;
if (write(p_in[1], &i, sizeof(i)) != sizeof(i))
return 1;
printf("Checking the victim alive\n");
pass = chk(p_out[0], 1);
pass = chk(p_out[0], 42);
if (!pass)
return 1;
/*
* Now do the infection with parasite.c
*/
printf("Infecting the victim\n");
if (do_infection(pid))
return 1;
/*
* Tell the victim some more stuff to check it's alive
*/
i = 1234;
if (write(p_in[1], &i, sizeof(i)) != sizeof(i))
return 1;
i = 4096;
if (write(p_in[1], &i, sizeof(i)) != sizeof(i))
return 1;
/*
* Stop the victim and check the infection went well
*/
printf("Closing victim stdin\n");
close(p_in[1]);
printf("Waiting for victim to die\n");
wait(NULL);
printf("Checking the result\n");
/* These two came from parasite */
pass = chk(p_out[0], 138);
pass = chk(p_out[0], 403);
/* These two came from post-infect */
pass = chk(p_out[0], 1234);
pass = chk(p_out[0], 4096);
if (pass)
printf("All OK\n");
else
printf("Something went WRONG\n");
return 0;
}