mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-28 12:57:57 +00:00
py: Reformat everything into pep8 style
As discussed on the mailing list, current .py files formatting does not conform to the world standard, so we should better reformat it. For this the yapf tool is used. The command I used was yapf -i $(find -name *.py) Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
5ff4fcb753
commit
5aa72e7237
@ -54,11 +54,8 @@ status = {
|
|||||||
"VMA_AREA_UNSUPP": 1 << 31
|
"VMA_AREA_UNSUPP": 1 << 31
|
||||||
}
|
}
|
||||||
|
|
||||||
prot = {
|
prot = {"PROT_READ": 0x1, "PROT_WRITE": 0x2, "PROT_EXEC": 0x4}
|
||||||
"PROT_READ" : 0x1,
|
|
||||||
"PROT_WRITE" : 0x2,
|
|
||||||
"PROT_EXEC" : 0x4
|
|
||||||
}
|
|
||||||
|
|
||||||
class elf_note:
|
class elf_note:
|
||||||
nhdr = None # Elf_Nhdr;
|
nhdr = None # Elf_Nhdr;
|
||||||
@ -75,6 +72,7 @@ class coredump:
|
|||||||
phdrs = [] # Array of Phdrs;
|
phdrs = [] # Array of Phdrs;
|
||||||
notes = [] # Array of elf_notes;
|
notes = [] # Array of elf_notes;
|
||||||
vmas = [] # Array of BytesIO with memory content;
|
vmas = [] # Array of BytesIO with memory content;
|
||||||
|
|
||||||
# FIXME keeping all vmas in memory is a bad idea;
|
# FIXME keeping all vmas in memory is a bad idea;
|
||||||
|
|
||||||
def write(self, f):
|
def write(self, f):
|
||||||
@ -146,7 +144,6 @@ class coredump_generator:
|
|||||||
else:
|
else:
|
||||||
return img["entries"]
|
return img["entries"]
|
||||||
|
|
||||||
|
|
||||||
def __call__(self, imgs_dir):
|
def __call__(self, imgs_dir):
|
||||||
"""
|
"""
|
||||||
Parse criu images stored in directory imgs_dir to fill core dumps.
|
Parse criu images stored in directory imgs_dir to fill core dumps.
|
||||||
@ -161,7 +158,8 @@ class coredump_generator:
|
|||||||
for tid in p['threads']:
|
for tid in p['threads']:
|
||||||
self.cores[tid] = self._img_open_and_strip("core", True, tid)
|
self.cores[tid] = self._img_open_and_strip("core", True, tid)
|
||||||
self.mms[pid] = self._img_open_and_strip("mm", True, pid)
|
self.mms[pid] = self._img_open_and_strip("mm", True, pid)
|
||||||
self.pagemaps[pid] = self._img_open_and_strip("pagemap", False, pid)
|
self.pagemaps[pid] = self._img_open_and_strip(
|
||||||
|
"pagemap", False, pid)
|
||||||
|
|
||||||
files = self._img_open_and_strip("files", False)
|
files = self._img_open_and_strip("files", False)
|
||||||
self.reg_files = [x["reg"] for x in files if x["type"] == "REG"]
|
self.reg_files = [x["reg"] for x in files if x["type"] == "REG"]
|
||||||
@ -171,7 +169,6 @@ class coredump_generator:
|
|||||||
|
|
||||||
return self.coredumps
|
return self.coredumps
|
||||||
|
|
||||||
|
|
||||||
def write(self, coredumps_dir, pid=None):
|
def write(self, coredumps_dir, pid=None):
|
||||||
"""
|
"""
|
||||||
Write core dumpt to cores_dir directory. Specify pid to choose
|
Write core dumpt to cores_dir directory. Specify pid to choose
|
||||||
@ -298,9 +295,11 @@ class coredump_generator:
|
|||||||
prpsinfo.pr_state = 3
|
prpsinfo.pr_state = 3
|
||||||
# Don't even ask me why it is so, just borrowed from linux
|
# Don't even ask me why it is so, just borrowed from linux
|
||||||
# source and made pr_state match.
|
# source and made pr_state match.
|
||||||
prpsinfo.pr_sname = '.' if prpsinfo.pr_state > 5 else "RSDTZW"[prpsinfo.pr_state]
|
prpsinfo.pr_sname = '.' if prpsinfo.pr_state > 5 else "RSDTZW" [
|
||||||
|
prpsinfo.pr_state]
|
||||||
prpsinfo.pr_zomb = 1 if prpsinfo.pr_state == 4 else 0
|
prpsinfo.pr_zomb = 1 if prpsinfo.pr_state == 4 else 0
|
||||||
prpsinfo.pr_nice = core["thread_core"]["sched_prio"] if "sched_prio" in core["thread_core"] else 0
|
prpsinfo.pr_nice = core["thread_core"][
|
||||||
|
"sched_prio"] if "sched_prio" in core["thread_core"] else 0
|
||||||
prpsinfo.pr_flag = core["tc"]["flags"]
|
prpsinfo.pr_flag = core["tc"]["flags"]
|
||||||
prpsinfo.pr_uid = core["thread_core"]["creds"]["uid"]
|
prpsinfo.pr_uid = core["thread_core"]["creds"]["uid"]
|
||||||
prpsinfo.pr_gid = core["thread_core"]["creds"]["gid"]
|
prpsinfo.pr_gid = core["thread_core"]["creds"]["gid"]
|
||||||
@ -399,8 +398,10 @@ class coredump_generator:
|
|||||||
fpregset.rdp = regs["rdp"]
|
fpregset.rdp = regs["rdp"]
|
||||||
fpregset.mxcsr = regs["mxcsr"]
|
fpregset.mxcsr = regs["mxcsr"]
|
||||||
fpregset.mxcr_mask = regs["mxcsr_mask"]
|
fpregset.mxcr_mask = regs["mxcsr_mask"]
|
||||||
fpregset.st_space = (ctypes.c_uint * len(regs["st_space"]))(*regs["st_space"])
|
fpregset.st_space = (ctypes.c_uint * len(regs["st_space"]))(
|
||||||
fpregset.xmm_space = (ctypes.c_uint * len(regs["xmm_space"]))(*regs["xmm_space"])
|
*regs["st_space"])
|
||||||
|
fpregset.xmm_space = (ctypes.c_uint * len(regs["xmm_space"]))(
|
||||||
|
*regs["xmm_space"])
|
||||||
#fpregset.padding = regs["padding"] unused
|
#fpregset.padding = regs["padding"] unused
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = elf.Elf64_Nhdr()
|
||||||
@ -433,12 +434,16 @@ class coredump_generator:
|
|||||||
data.i387.rdp = fpregs["rdp"]
|
data.i387.rdp = fpregs["rdp"]
|
||||||
data.i387.mxcsr = fpregs["mxcsr"]
|
data.i387.mxcsr = fpregs["mxcsr"]
|
||||||
data.i387.mxcsr_mask = fpregs["mxcsr_mask"]
|
data.i387.mxcsr_mask = fpregs["mxcsr_mask"]
|
||||||
data.i387.st_space = (ctypes.c_uint * len(fpregs["st_space"]))(*fpregs["st_space"])
|
data.i387.st_space = (ctypes.c_uint * len(fpregs["st_space"]))(
|
||||||
data.i387.xmm_space = (ctypes.c_uint * len(fpregs["xmm_space"]))(*fpregs["xmm_space"])
|
*fpregs["st_space"])
|
||||||
|
data.i387.xmm_space = (ctypes.c_uint * len(fpregs["xmm_space"]))(
|
||||||
|
*fpregs["xmm_space"])
|
||||||
|
|
||||||
if "xsave" in fpregs:
|
if "xsave" in fpregs:
|
||||||
data.xsave_hdr.xstate_bv = fpregs["xsave"]["xstate_bv"]
|
data.xsave_hdr.xstate_bv = fpregs["xsave"]["xstate_bv"]
|
||||||
data.ymmh.ymmh_space = (ctypes.c_uint * len(fpregs["xsave"]["ymmh_space"]))(*fpregs["xsave"]["ymmh_space"])
|
data.ymmh.ymmh_space = (ctypes.c_uint *
|
||||||
|
len(fpregs["xsave"]["ymmh_space"]))(
|
||||||
|
*fpregs["xsave"]["ymmh_space"])
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = elf.Elf64_Nhdr()
|
||||||
nhdr.n_namesz = 6
|
nhdr.n_namesz = 6
|
||||||
@ -551,7 +556,8 @@ class coredump_generator:
|
|||||||
fields.append(("end" + str(i), ctypes.c_long))
|
fields.append(("end" + str(i), ctypes.c_long))
|
||||||
fields.append(("file_ofs" + str(i), ctypes.c_long))
|
fields.append(("file_ofs" + str(i), ctypes.c_long))
|
||||||
for i in range(len(infos)):
|
for i in range(len(infos)):
|
||||||
fields.append(("name"+str(i), ctypes.c_char*(len(infos[i].name)+1)))
|
fields.append(
|
||||||
|
("name" + str(i), ctypes.c_char * (len(infos[i].name) + 1)))
|
||||||
|
|
||||||
class elf_files(ctypes.Structure):
|
class elf_files(ctypes.Structure):
|
||||||
_fields_ = fields
|
_fields_ = fields
|
||||||
@ -639,7 +645,8 @@ class coredump_generator:
|
|||||||
ppid = self.pstree[pid]["ppid"]
|
ppid = self.pstree[pid]["ppid"]
|
||||||
return self._get_page(ppid, page_no)
|
return self._get_page(ppid, page_no)
|
||||||
else:
|
else:
|
||||||
with open(self._imgs_dir+"/"+"pages-"+str(pages_id)+".img") as f:
|
with open(self._imgs_dir + "/" + "pages-" + str(pages_id) +
|
||||||
|
".img") as f:
|
||||||
f.seek(off * PAGESIZE)
|
f.seek(off * PAGESIZE)
|
||||||
return f.read(PAGESIZE)
|
return f.read(PAGESIZE)
|
||||||
|
|
||||||
|
@ -16,13 +16,16 @@ EI_MAG0 = 0 # #define EI_MAG0 0 /* File identification b
|
|||||||
ELFMAG0 = 0x7f # #define ELFMAG0 0x7f /* Magic number byte 0 */
|
ELFMAG0 = 0x7f # #define ELFMAG0 0x7f /* Magic number byte 0 */
|
||||||
|
|
||||||
EI_MAG1 = 1 # #define EI_MAG1 1 /* File identification byte 1 index */
|
EI_MAG1 = 1 # #define EI_MAG1 1 /* File identification byte 1 index */
|
||||||
ELFMAG1 = ord('E') # #define ELFMAG1 'E' /* Magic number byte 1 */
|
ELFMAG1 = ord(
|
||||||
|
'E') # #define ELFMAG1 'E' /* Magic number byte 1 */
|
||||||
|
|
||||||
EI_MAG2 = 2 # #define EI_MAG2 2 /* File identification byte 2 index */
|
EI_MAG2 = 2 # #define EI_MAG2 2 /* File identification byte 2 index */
|
||||||
ELFMAG2 = ord('L') # #define ELFMAG2 'L' /* Magic number byte 2 */
|
ELFMAG2 = ord(
|
||||||
|
'L') # #define ELFMAG2 'L' /* Magic number byte 2 */
|
||||||
|
|
||||||
EI_MAG3 = 3 # #define EI_MAG3 3 /* File identification byte 3 index */
|
EI_MAG3 = 3 # #define EI_MAG3 3 /* File identification byte 3 index */
|
||||||
ELFMAG3 = ord('F') # #define ELFMAG3 'F' /* Magic number byte 3 */
|
ELFMAG3 = ord(
|
||||||
|
'F') # #define ELFMAG3 'F' /* Magic number byte 3 */
|
||||||
|
|
||||||
EI_CLASS = 4 # #define EI_CLASS 4 /* File class byte index */
|
EI_CLASS = 4 # #define EI_CLASS 4 /* File class byte index */
|
||||||
|
|
||||||
@ -43,9 +46,11 @@ EM_X86_64 = 62 # #define EM_X86_64 62 /* AMD x86-64 architec
|
|||||||
# Legal values for e_version (version).
|
# Legal values for e_version (version).
|
||||||
EV_CURRENT = 1 # #define EV_CURRENT 1 /* Current version */
|
EV_CURRENT = 1 # #define EV_CURRENT 1 /* Current version */
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Ehdr(ctypes.Structure): # typedef struct
|
class Elf64_Ehdr(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("e_ident", ctypes.c_ubyte*EI_NIDENT), # unsigned char e_ident[EI_NIDENT];
|
("e_ident",
|
||||||
|
ctypes.c_ubyte * EI_NIDENT), # unsigned char e_ident[EI_NIDENT];
|
||||||
("e_type", Elf64_Half), # Elf64_Half e_type;
|
("e_type", Elf64_Half), # Elf64_Half e_type;
|
||||||
("e_machine", Elf64_Half), # Elf64_Half e_machine;
|
("e_machine", Elf64_Half), # Elf64_Half e_machine;
|
||||||
("e_version", Elf64_Word), # Elf64_Word e_version;
|
("e_version", Elf64_Word), # Elf64_Word e_version;
|
||||||
@ -73,6 +78,7 @@ PF_X = 1 # #define PF_X (1 << 0) /* Segment is executable */
|
|||||||
PF_W = 1 << 1 # #define PF_W (1 << 1) /* Segment is writable */
|
PF_W = 1 << 1 # #define PF_W (1 << 1) /* Segment is writable */
|
||||||
PF_R = 1 << 2 # #define PF_R (1 << 2) /* Segment is readable */
|
PF_R = 1 << 2 # #define PF_R (1 << 2) /* Segment is readable */
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Phdr(ctypes.Structure): # typedef struct
|
class Elf64_Phdr(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("p_type", Elf64_Word), # Elf64_Word p_type;
|
("p_type", Elf64_Word), # Elf64_Word p_type;
|
||||||
@ -88,14 +94,15 @@ class Elf64_Phdr(ctypes.Structure): # typedef struct
|
|||||||
|
|
||||||
# Elf64_auxv_t related constants.
|
# Elf64_auxv_t related constants.
|
||||||
|
|
||||||
|
|
||||||
class _Elf64_auxv_t_U(ctypes.Union):
|
class _Elf64_auxv_t_U(ctypes.Union):
|
||||||
_fields_ = [
|
_fields_ = [("a_val", ctypes.c_uint64)]
|
||||||
("a_val", ctypes.c_uint64)
|
|
||||||
]
|
|
||||||
|
|
||||||
class Elf64_auxv_t(ctypes.Structure): # typedef struct
|
class Elf64_auxv_t(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("a_type", ctypes.c_uint64), # uint64_t a_type; /* Entry type */
|
("a_type",
|
||||||
|
ctypes.c_uint64), # uint64_t a_type; /* Entry type */
|
||||||
("a_un", _Elf64_auxv_t_U) # union
|
("a_un", _Elf64_auxv_t_U) # union
|
||||||
# {
|
# {
|
||||||
# uint64_t a_val; /* Integer value */
|
# uint64_t a_val; /* Integer value */
|
||||||
@ -118,101 +125,178 @@ NT_FILE = 0x46494c45 # #define NT_FILE 0x46494c45 /* Contains info
|
|||||||
# files */
|
# files */
|
||||||
NT_X86_XSTATE = 0x202 # #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
|
NT_X86_XSTATE = 0x202 # #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Nhdr(ctypes.Structure): # typedef struct
|
class Elf64_Nhdr(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("n_namesz", Elf64_Word), # Elf64_Word n_namesz; /* Length of the note's name. */
|
(
|
||||||
("n_descsz", Elf64_Word), # Elf64_Word n_descsz; /* Length of the note's descriptor. */
|
"n_namesz", Elf64_Word
|
||||||
("n_type", Elf64_Word), # Elf64_Word n_type; /* Type of the note. */
|
), # Elf64_Word n_namesz; /* Length of the note's name. */
|
||||||
|
(
|
||||||
|
"n_descsz", Elf64_Word
|
||||||
|
), # Elf64_Word n_descsz; /* Length of the note's descriptor. */
|
||||||
|
("n_type", Elf64_Word
|
||||||
|
), # Elf64_Word n_type; /* Type of the note. */
|
||||||
] # } Elf64_Nhdr;
|
] # } Elf64_Nhdr;
|
||||||
|
|
||||||
|
|
||||||
# Elf64_Shdr related constants.
|
# Elf64_Shdr related constants.
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Shdr(ctypes.Structure): # typedef struct
|
class Elf64_Shdr(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("sh_name", Elf64_Word), # Elf64_Word sh_name; /* Section name (string tbl index) */
|
(
|
||||||
("sh_type", Elf64_Word), # Elf64_Word sh_type; /* Section type */
|
"sh_name", Elf64_Word
|
||||||
("sh_flags", Elf64_Xword), # Elf64_Xword sh_flags; /* Section flags */
|
), # Elf64_Word sh_name; /* Section name (string tbl index) */
|
||||||
("sh_addr", Elf64_Addr), # Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
("sh_type", Elf64_Word
|
||||||
("sh_offset", Elf64_Off), # Elf64_Off sh_offset; /* Section file offset */
|
), # Elf64_Word sh_type; /* Section type */
|
||||||
("sh_size", Elf64_Xword), # Elf64_Xword sh_size; /* Section size in bytes */
|
("sh_flags", Elf64_Xword
|
||||||
("sh_link", Elf64_Word), # Elf64_Word sh_link; /* Link to another section */
|
), # Elf64_Xword sh_flags; /* Section flags */
|
||||||
("sh_info", Elf64_Word), # Elf64_Word sh_info; /* Additional section information */
|
(
|
||||||
("sh_addralign",Elf64_Xword), # Elf64_Xword sh_addralign; /* Section alignment */
|
"sh_addr", Elf64_Addr
|
||||||
("sh_entsize", Elf64_Xword) # Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
), # Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
||||||
|
(
|
||||||
|
"sh_offset", Elf64_Off
|
||||||
|
), # Elf64_Off sh_offset; /* Section file offset */
|
||||||
|
(
|
||||||
|
"sh_size", Elf64_Xword
|
||||||
|
), # Elf64_Xword sh_size; /* Section size in bytes */
|
||||||
|
(
|
||||||
|
"sh_link", Elf64_Word
|
||||||
|
), # Elf64_Word sh_link; /* Link to another section */
|
||||||
|
(
|
||||||
|
"sh_info", Elf64_Word
|
||||||
|
), # Elf64_Word sh_info; /* Additional section information */
|
||||||
|
("sh_addralign", Elf64_Xword
|
||||||
|
), # Elf64_Xword sh_addralign; /* Section alignment */
|
||||||
|
(
|
||||||
|
"sh_entsize", Elf64_Xword
|
||||||
|
) # Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||||
] # } Elf64_Shdr;
|
] # } Elf64_Shdr;
|
||||||
|
|
||||||
|
|
||||||
# elf_prstatus related constants.
|
# elf_prstatus related constants.
|
||||||
|
|
||||||
|
|
||||||
# Signal info.
|
# Signal info.
|
||||||
class elf_siginfo(ctypes.Structure): # struct elf_siginfo
|
class elf_siginfo(ctypes.Structure): # struct elf_siginfo
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_signo", ctypes.c_int), # int si_signo; /* Signal number. */
|
("si_signo", ctypes.c_int
|
||||||
("si_code", ctypes.c_int), # int si_code; /* Extra code. */
|
), # int si_signo; /* Signal number. */
|
||||||
("si_errno", ctypes.c_int) # int si_errno; /* Errno. */
|
("si_code", ctypes.c_int
|
||||||
|
), # int si_code; /* Extra code. */
|
||||||
|
("si_errno", ctypes.c_int
|
||||||
|
) # int si_errno; /* Errno. */
|
||||||
] # };
|
] # };
|
||||||
|
|
||||||
|
|
||||||
# A time value that is accurate to the nearest
|
# A time value that is accurate to the nearest
|
||||||
# microsecond but also has a range of years.
|
# microsecond but also has a range of years.
|
||||||
class timeval(ctypes.Structure): # struct timeval
|
class timeval(ctypes.Structure): # struct timeval
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("tv_sec", ctypes.c_long), # __time_t tv_sec; /* Seconds. */
|
("tv_sec",
|
||||||
("tv_usec", ctypes.c_long) # __suseconds_t tv_usec; /* Microseconds. */
|
ctypes.c_long), # __time_t tv_sec; /* Seconds. */
|
||||||
|
("tv_usec", ctypes.c_long
|
||||||
|
) # __suseconds_t tv_usec; /* Microseconds. */
|
||||||
] # };
|
] # };
|
||||||
|
|
||||||
|
|
||||||
class user_regs_struct(ctypes.Structure): # struct user_regs_struct
|
class user_regs_struct(ctypes.Structure): # struct user_regs_struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("r15", ctypes.c_ulonglong), # __extension__ unsigned long long int r15;
|
("r15",
|
||||||
("r14", ctypes.c_ulonglong), # __extension__ unsigned long long int r14;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r15;
|
||||||
("r13", ctypes.c_ulonglong), # __extension__ unsigned long long int r13;
|
("r14",
|
||||||
("r12", ctypes.c_ulonglong), # __extension__ unsigned long long int r12;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r14;
|
||||||
("rbp", ctypes.c_ulonglong), # __extension__ unsigned long long int rbp;
|
("r13",
|
||||||
("rbx", ctypes.c_ulonglong), # __extension__ unsigned long long int rbx;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r13;
|
||||||
("r11", ctypes.c_ulonglong), # __extension__ unsigned long long int r11;
|
("r12",
|
||||||
("r10", ctypes.c_ulonglong), # __extension__ unsigned long long int r10;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r12;
|
||||||
("r9", ctypes.c_ulonglong), # __extension__ unsigned long long int r9;
|
("rbp",
|
||||||
("r8", ctypes.c_ulonglong), # __extension__ unsigned long long int r8;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rbp;
|
||||||
("rax", ctypes.c_ulonglong), # __extension__ unsigned long long int rax;
|
("rbx",
|
||||||
("rcx", ctypes.c_ulonglong), # __extension__ unsigned long long int rcx;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rbx;
|
||||||
("rdx", ctypes.c_ulonglong), # __extension__ unsigned long long int rdx;
|
("r11",
|
||||||
("rsi", ctypes.c_ulonglong), # __extension__ unsigned long long int rsi;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r11;
|
||||||
("rdi", ctypes.c_ulonglong), # __extension__ unsigned long long int rdi;
|
("r10",
|
||||||
("orig_rax", ctypes.c_ulonglong), # __extension__ unsigned long long int orig_rax;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r10;
|
||||||
("rip", ctypes.c_ulonglong), # __extension__ unsigned long long int rip;
|
("r9",
|
||||||
("cs", ctypes.c_ulonglong), # __extension__ unsigned long long int cs;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r9;
|
||||||
("eflags", ctypes.c_ulonglong), # __extension__ unsigned long long int eflags;
|
("r8",
|
||||||
("rsp", ctypes.c_ulonglong), # __extension__ unsigned long long int rsp;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int r8;
|
||||||
("ss", ctypes.c_ulonglong), # __extension__ unsigned long long int ss;
|
("rax",
|
||||||
("fs_base", ctypes.c_ulonglong), # __extension__ unsigned long long int fs_base;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rax;
|
||||||
("gs_base", ctypes.c_ulonglong), # __extension__ unsigned long long int gs_base;
|
("rcx",
|
||||||
("ds", ctypes.c_ulonglong), # __extension__ unsigned long long int ds;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rcx;
|
||||||
("es", ctypes.c_ulonglong), # __extension__ unsigned long long int es;
|
("rdx",
|
||||||
("fs", ctypes.c_ulonglong), # __extension__ unsigned long long int fs;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rdx;
|
||||||
("gs", ctypes.c_ulonglong) # __extension__ unsigned long long int gs;
|
("rsi",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rsi;
|
||||||
|
("rdi",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rdi;
|
||||||
|
("orig_rax", ctypes.c_ulonglong
|
||||||
|
), # __extension__ unsigned long long int orig_rax;
|
||||||
|
("rip",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rip;
|
||||||
|
("cs",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int cs;
|
||||||
|
("eflags",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int eflags;
|
||||||
|
("rsp",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rsp;
|
||||||
|
("ss",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int ss;
|
||||||
|
("fs_base", ctypes.c_ulonglong
|
||||||
|
), # __extension__ unsigned long long int fs_base;
|
||||||
|
("gs_base", ctypes.c_ulonglong
|
||||||
|
), # __extension__ unsigned long long int gs_base;
|
||||||
|
("ds",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int ds;
|
||||||
|
("es",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int es;
|
||||||
|
("fs",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int fs;
|
||||||
|
("gs", ctypes.c_ulonglong
|
||||||
|
) # __extension__ unsigned long long int gs;
|
||||||
] # };
|
] # };
|
||||||
|
|
||||||
|
|
||||||
#elf_greg_t = ctypes.c_ulonglong
|
#elf_greg_t = ctypes.c_ulonglong
|
||||||
#ELF_NGREG = ctypes.sizeof(user_regs_struct)/ctypes.sizeof(elf_greg_t)
|
#ELF_NGREG = ctypes.sizeof(user_regs_struct)/ctypes.sizeof(elf_greg_t)
|
||||||
#elf_gregset_t = elf_greg_t*ELF_NGREG
|
#elf_gregset_t = elf_greg_t*ELF_NGREG
|
||||||
elf_gregset_t = user_regs_struct
|
elf_gregset_t = user_regs_struct
|
||||||
|
|
||||||
|
|
||||||
class elf_prstatus(ctypes.Structure): # struct elf_prstatus
|
class elf_prstatus(ctypes.Structure): # struct elf_prstatus
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("pr_info", elf_siginfo), # struct elf_siginfo pr_info; /* Info associated with signal. */
|
(
|
||||||
("pr_cursig", ctypes.c_short), # short int pr_cursig; /* Current signal. */
|
"pr_info", elf_siginfo
|
||||||
("pr_sigpend", ctypes.c_ulong), # unsigned long int pr_sigpend; /* Set of pending signals. */
|
), # struct elf_siginfo pr_info; /* Info associated with signal. */
|
||||||
("pr_sighold", ctypes.c_ulong), # unsigned long int pr_sighold; /* Set of held signals. */
|
("pr_cursig", ctypes.c_short
|
||||||
|
), # short int pr_cursig; /* Current signal. */
|
||||||
|
(
|
||||||
|
"pr_sigpend", ctypes.c_ulong
|
||||||
|
), # unsigned long int pr_sigpend; /* Set of pending signals. */
|
||||||
|
(
|
||||||
|
"pr_sighold", ctypes.c_ulong
|
||||||
|
), # unsigned long int pr_sighold; /* Set of held signals. */
|
||||||
("pr_pid", ctypes.c_int), # __pid_t pr_pid;
|
("pr_pid", ctypes.c_int), # __pid_t pr_pid;
|
||||||
("pr_ppid", ctypes.c_int), # __pid_t pr_ppid;
|
("pr_ppid", ctypes.c_int), # __pid_t pr_ppid;
|
||||||
("pr_pgrp", ctypes.c_int), # __pid_t pr_pgrp;
|
("pr_pgrp", ctypes.c_int), # __pid_t pr_pgrp;
|
||||||
("pr_sid", ctypes.c_int), # __pid_t pr_sid;
|
("pr_sid", ctypes.c_int), # __pid_t pr_sid;
|
||||||
("pr_utime", timeval), # struct timeval pr_utime; /* User time. */
|
("pr_utime",
|
||||||
("pr_stime", timeval), # struct timeval pr_stime; /* System time. */
|
timeval), # struct timeval pr_utime; /* User time. */
|
||||||
("pr_cutime", timeval), # struct timeval pr_cutime; /* Cumulative user time. */
|
("pr_stime", timeval
|
||||||
("pr_cstime", timeval), # struct timeval pr_cstime; /* Cumulative system time. */
|
), # struct timeval pr_stime; /* System time. */
|
||||||
("pr_reg", elf_gregset_t), # elf_gregset_t pr_reg; /* GP registers. */
|
(
|
||||||
("pr_fpvalid", ctypes.c_int) # int pr_fpvalid; /* True if math copro being used. */
|
"pr_cutime", timeval
|
||||||
|
), # struct timeval pr_cutime; /* Cumulative user time. */
|
||||||
|
(
|
||||||
|
"pr_cstime", timeval
|
||||||
|
), # struct timeval pr_cstime; /* Cumulative system time. */
|
||||||
|
("pr_reg", elf_gregset_t
|
||||||
|
), # elf_gregset_t pr_reg; /* GP registers. */
|
||||||
|
(
|
||||||
|
"pr_fpvalid", ctypes.c_int
|
||||||
|
) # int pr_fpvalid; /* True if math copro being used. */
|
||||||
] # };
|
] # };
|
||||||
|
|
||||||
|
|
||||||
@ -220,13 +304,21 @@ class elf_prstatus(ctypes.Structure): # struct elf_prstatus
|
|||||||
|
|
||||||
ELF_PRARGSZ = 80 # #define ELF_PRARGSZ (80) /* Number of chars for args. */
|
ELF_PRARGSZ = 80 # #define ELF_PRARGSZ (80) /* Number of chars for args. */
|
||||||
|
|
||||||
|
|
||||||
class elf_prpsinfo(ctypes.Structure): # struct elf_prpsinfo
|
class elf_prpsinfo(ctypes.Structure): # struct elf_prpsinfo
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("pr_state", ctypes.c_byte), # char pr_state; /* Numeric process state. */
|
(
|
||||||
("pr_sname", ctypes.c_char), # char pr_sname; /* Char for pr_state. */
|
"pr_state", ctypes.c_byte
|
||||||
("pr_zomb", ctypes.c_byte), # char pr_zomb; /* Zombie. */
|
), # char pr_state; /* Numeric process state. */
|
||||||
("pr_nice", ctypes.c_byte), # char pr_nice; /* Nice val. */
|
(
|
||||||
("pr_flag", ctypes.c_ulong), # unsigned long int pr_flag; /* Flags. */
|
"pr_sname", ctypes.c_char
|
||||||
|
), # char pr_sname; /* Char for pr_state. */
|
||||||
|
("pr_zomb", ctypes.c_byte
|
||||||
|
), # char pr_zomb; /* Zombie. */
|
||||||
|
("pr_nice", ctypes.c_byte
|
||||||
|
), # char pr_nice; /* Nice val. */
|
||||||
|
("pr_flag", ctypes.c_ulong
|
||||||
|
), # unsigned long int pr_flag; /* Flags. */
|
||||||
# #if __WORDSIZE == 32
|
# #if __WORDSIZE == 32
|
||||||
# unsigned short int pr_uid;
|
# unsigned short int pr_uid;
|
||||||
# unsigned short int pr_gid;
|
# unsigned short int pr_gid;
|
||||||
@ -239,8 +331,12 @@ class elf_prpsinfo(ctypes.Structure): # struct elf_prpsinfo
|
|||||||
("pr_pgrp", ctypes.c_int),
|
("pr_pgrp", ctypes.c_int),
|
||||||
("pr_sid", ctypes.c_int),
|
("pr_sid", ctypes.c_int),
|
||||||
# /* Lots missing */
|
# /* Lots missing */
|
||||||
("pr_fname", ctypes.c_char*16), # char pr_fname[16]; /* Filename of executable. */
|
(
|
||||||
("pr_psargs", ctypes.c_char*ELF_PRARGSZ) # char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
|
"pr_fname", ctypes.c_char * 16
|
||||||
|
), # char pr_fname[16]; /* Filename of executable. */
|
||||||
|
(
|
||||||
|
"pr_psargs", ctypes.c_char * ELF_PRARGSZ
|
||||||
|
) # char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
|
||||||
] # };
|
] # };
|
||||||
|
|
||||||
|
|
||||||
@ -250,33 +346,42 @@ class user_fpregs_struct(ctypes.Structure): # struct user_fpregs_struct
|
|||||||
("swd", ctypes.c_ushort), # unsigned short int swd;
|
("swd", ctypes.c_ushort), # unsigned short int swd;
|
||||||
("ftw", ctypes.c_ushort), # unsigned short int ftw;
|
("ftw", ctypes.c_ushort), # unsigned short int ftw;
|
||||||
("fop", ctypes.c_ushort), # unsigned short int fop;
|
("fop", ctypes.c_ushort), # unsigned short int fop;
|
||||||
("rip", ctypes.c_ulonglong), # __extension__ unsigned long long int rip;
|
("rip",
|
||||||
("rdp", ctypes.c_ulonglong), # __extension__ unsigned long long int rdp;
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rip;
|
||||||
|
("rdp",
|
||||||
|
ctypes.c_ulonglong), # __extension__ unsigned long long int rdp;
|
||||||
("mxcsr", ctypes.c_uint), # unsigned int mxcsr;
|
("mxcsr", ctypes.c_uint), # unsigned int mxcsr;
|
||||||
("mxcr_mask", ctypes.c_uint), # unsigned int mxcr_mask;
|
("mxcr_mask", ctypes.c_uint), # unsigned int mxcr_mask;
|
||||||
("st_space", ctypes.c_uint*32), # unsigned int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
|
(
|
||||||
("xmm_space", ctypes.c_uint*64), # unsigned int xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
|
"st_space", ctypes.c_uint * 32
|
||||||
("padding", ctypes.c_uint*24), # unsigned int padding[24];
|
), # unsigned int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
|
||||||
|
(
|
||||||
|
"xmm_space", ctypes.c_uint * 64
|
||||||
|
), # unsigned int xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
|
||||||
|
("padding",
|
||||||
|
ctypes.c_uint * 24), # unsigned int padding[24];
|
||||||
] # };
|
] # };
|
||||||
|
|
||||||
|
|
||||||
elf_fpregset_t = user_fpregs_struct
|
elf_fpregset_t = user_fpregs_struct
|
||||||
|
|
||||||
|
|
||||||
# siginfo_t related constants.
|
# siginfo_t related constants.
|
||||||
|
|
||||||
_SI_MAX_SIZE = 128
|
_SI_MAX_SIZE = 128
|
||||||
_SI_PAD_SIZE = (_SI_MAX_SIZE / ctypes.sizeof(ctypes.c_int)) - 4
|
_SI_PAD_SIZE = (_SI_MAX_SIZE / ctypes.sizeof(ctypes.c_int)) - 4
|
||||||
|
|
||||||
|
|
||||||
# /* kill(). */
|
# /* kill(). */
|
||||||
class _siginfo_t_U_kill(ctypes.Structure): # struct
|
class _siginfo_t_U_kill(ctypes.Structure): # struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_pid", ctypes.c_int), # __pid_t si_pid; /* Sending process ID. */
|
("si_pid", ctypes.c_int
|
||||||
("si_uid", ctypes.c_uint) # __uid_t si_uid; /* Real user ID of sending process. */
|
), # __pid_t si_pid; /* Sending process ID. */
|
||||||
|
(
|
||||||
|
"si_uid", ctypes.c_uint
|
||||||
|
) # __uid_t si_uid; /* Real user ID of sending process. */
|
||||||
] # } _kill;
|
] # } _kill;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Type for data associated with a signal.
|
# Type for data associated with a signal.
|
||||||
class sigval_t(ctypes.Union): # typedef union sigval
|
class sigval_t(ctypes.Union): # typedef union sigval
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
@ -284,45 +389,63 @@ class sigval_t(ctypes.Union): # typedef union sigval
|
|||||||
("sical_ptr", ctypes.c_void_p), # void *sival_ptr;
|
("sical_ptr", ctypes.c_void_p), # void *sival_ptr;
|
||||||
] # } sigval_t;
|
] # } sigval_t;
|
||||||
|
|
||||||
|
|
||||||
# /* POSIX.1b timers. */
|
# /* POSIX.1b timers. */
|
||||||
class _siginfo_t_U_timer(ctypes.Structure): # struct
|
class _siginfo_t_U_timer(ctypes.Structure): # struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_tid", ctypes.c_int), # int si_tid; /* Timer ID. */
|
("si_tid",
|
||||||
("si_overrun", ctypes.c_int), # int si_overrun; /* Overrun count. */
|
ctypes.c_int), # int si_tid; /* Timer ID. */
|
||||||
("si_sigval", sigval_t) # sigval_t si_sigval; /* Signal value. */
|
("si_overrun", ctypes.c_int
|
||||||
|
), # int si_overrun; /* Overrun count. */
|
||||||
|
("si_sigval", sigval_t
|
||||||
|
) # sigval_t si_sigval; /* Signal value. */
|
||||||
] # } _timer;
|
] # } _timer;
|
||||||
|
|
||||||
|
|
||||||
# /* POSIX.1b signals. */
|
# /* POSIX.1b signals. */
|
||||||
class _siginfo_t_U_rt(ctypes.Structure): # struct
|
class _siginfo_t_U_rt(ctypes.Structure): # struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_pid", ctypes.c_int), # __pid_t si_pid; /* Sending process ID. */
|
("si_pid", ctypes.c_int
|
||||||
("si_uid", ctypes.c_uint), # __uid_t si_uid; /* Real user ID of sending process. */
|
), # __pid_t si_pid; /* Sending process ID. */
|
||||||
("si_sigval", sigval_t) # sigval_t si_sigval; /* Signal value. */
|
(
|
||||||
|
"si_uid", ctypes.c_uint
|
||||||
|
), # __uid_t si_uid; /* Real user ID of sending process. */
|
||||||
|
("si_sigval", sigval_t
|
||||||
|
) # sigval_t si_sigval; /* Signal value. */
|
||||||
] # } _rt;
|
] # } _rt;
|
||||||
|
|
||||||
|
|
||||||
# /* SIGCHLD. */
|
# /* SIGCHLD. */
|
||||||
class _siginfo_t_U_sigchld(ctypes.Structure): # struct
|
class _siginfo_t_U_sigchld(ctypes.Structure): # struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_pid", ctypes.c_int), # __pid_t si_pid; /* Which child. */
|
("si_pid",
|
||||||
("si_uid", ctypes.c_uint), # __uid_t si_uid; /* Real user ID of sending process. */
|
ctypes.c_int), # __pid_t si_pid; /* Which child. */
|
||||||
("si_status", ctypes.c_int), # int si_status; /* Exit value or signal. */
|
(
|
||||||
|
"si_uid", ctypes.c_uint
|
||||||
|
), # __uid_t si_uid; /* Real user ID of sending process. */
|
||||||
|
("si_status", ctypes.c_int
|
||||||
|
), # int si_status; /* Exit value or signal. */
|
||||||
("si_utime", ctypes.c_long), # __sigchld_clock_t si_utime;
|
("si_utime", ctypes.c_long), # __sigchld_clock_t si_utime;
|
||||||
("si_stime", ctypes.c_long) # __sigchld_clock_t si_stime;
|
("si_stime", ctypes.c_long) # __sigchld_clock_t si_stime;
|
||||||
] # } _sigchld;
|
] # } _sigchld;
|
||||||
|
|
||||||
|
|
||||||
# /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
|
# /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
|
||||||
class _siginfo_t_U_sigfault(ctypes.Structure): # struct
|
class _siginfo_t_U_sigfault(ctypes.Structure): # struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_addr", ctypes.c_void_p), # void *si_addr; /* Faulting insn/memory ref. */
|
("si_addr", ctypes.c_void_p
|
||||||
("si_addr_lsb", ctypes.c_short) # short int si_addr_lsb; /* Valid LSB of the reported address. */
|
), # void *si_addr; /* Faulting insn/memory ref. */
|
||||||
|
(
|
||||||
|
"si_addr_lsb", ctypes.c_short
|
||||||
|
) # short int si_addr_lsb; /* Valid LSB of the reported address. */
|
||||||
] # } _sigfault;
|
] # } _sigfault;
|
||||||
|
|
||||||
|
|
||||||
# /* SIGPOLL. */
|
# /* SIGPOLL. */
|
||||||
class _siginfo_t_U_sigpoll(ctypes.Structure): # struct
|
class _siginfo_t_U_sigpoll(ctypes.Structure): # struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_band", ctypes.c_long), # long int si_band; /* Band event for SIGPOLL. */
|
("si_band", ctypes.c_long
|
||||||
|
), # long int si_band; /* Band event for SIGPOLL. */
|
||||||
("si_fd", ctypes.c_int) # int si_fd;
|
("si_fd", ctypes.c_int) # int si_fd;
|
||||||
] # } _sigpoll;
|
] # } _sigpoll;
|
||||||
|
|
||||||
@ -330,15 +453,20 @@ class _siginfo_t_U_sigpoll(ctypes.Structure): # struct
|
|||||||
# /* SIGSYS. */
|
# /* SIGSYS. */
|
||||||
class _siginfo_t_U_sigsys(ctypes.Structure): # struct
|
class _siginfo_t_U_sigsys(ctypes.Structure): # struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("_call_addr", ctypes.c_void_p), # void *_call_addr; /* Calling user insn. */
|
("_call_addr", ctypes.c_void_p
|
||||||
("_syscall", ctypes.c_int), # int _syscall; /* Triggering system call number. */
|
), # void *_call_addr; /* Calling user insn. */
|
||||||
("_arch", ctypes.c_uint) # unsigned int _arch; /* AUDIT_ARCH_* of syscall. */
|
(
|
||||||
|
"_syscall", ctypes.c_int
|
||||||
|
), # int _syscall; /* Triggering system call number. */
|
||||||
|
("_arch", ctypes.c_uint
|
||||||
|
) # unsigned int _arch; /* AUDIT_ARCH_* of syscall. */
|
||||||
] # } _sigsys;
|
] # } _sigsys;
|
||||||
|
|
||||||
|
|
||||||
class _siginfo_t_U(ctypes.Union): # union
|
class _siginfo_t_U(ctypes.Union): # union
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("_pad", ctypes.c_int*_SI_PAD_SIZE), # int _pad[__SI_PAD_SIZE];
|
("_pad",
|
||||||
|
ctypes.c_int * _SI_PAD_SIZE), # int _pad[__SI_PAD_SIZE];
|
||||||
#
|
#
|
||||||
# /* kill(). */
|
# /* kill(). */
|
||||||
("_kill", _siginfo_t_U_kill), # struct
|
("_kill", _siginfo_t_U_kill), # struct
|
||||||
@ -396,12 +524,17 @@ class _siginfo_t_U(ctypes.Union): # union
|
|||||||
# } _sigsys;
|
# } _sigsys;
|
||||||
] # } _sifields;
|
] # } _sifields;
|
||||||
|
|
||||||
|
|
||||||
class siginfo_t(ctypes.Structure): # typedef struct
|
class siginfo_t(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [ # {
|
_fields_ = [ # {
|
||||||
("si_signo", ctypes.c_int), # int si_signo; /* Signal number. */
|
("si_signo", ctypes.c_int
|
||||||
("si_errno", ctypes.c_int), # int si_errno; /* If non-zero, an errno value associated with
|
), # int si_signo; /* Signal number. */
|
||||||
|
(
|
||||||
|
"si_errno", ctypes.c_int
|
||||||
|
), # int si_errno; /* If non-zero, an errno value associated with
|
||||||
# this signal, as defined in <errno.h>. */
|
# this signal, as defined in <errno.h>. */
|
||||||
("si_code", ctypes.c_int), # int si_code; /* Signal code. */
|
("si_code", ctypes.c_int
|
||||||
|
), # int si_code; /* Signal code. */
|
||||||
#
|
#
|
||||||
("_sifields", _siginfo_t_U) # union
|
("_sifields", _siginfo_t_U) # union
|
||||||
# {
|
# {
|
||||||
@ -467,30 +600,46 @@ class siginfo_t(ctypes.Structure): # typedef struct
|
|||||||
|
|
||||||
# xsave related.
|
# xsave related.
|
||||||
|
|
||||||
|
|
||||||
class ymmh_struct(ctypes.Structure): # struct ymmh_struct {
|
class ymmh_struct(ctypes.Structure): # struct ymmh_struct {
|
||||||
_fields_ = [
|
_fields_ = [("ymmh_space", 64 * ctypes.c_uint
|
||||||
("ymmh_space", 64*ctypes.c_uint) # u32 ymmh_space[64];
|
) # u32 ymmh_space[64];
|
||||||
] # } __packed;
|
] # } __packed;
|
||||||
|
|
||||||
|
|
||||||
class xsave_hdr_struct(ctypes.Structure): # struct xsave_hdr_struct {
|
class xsave_hdr_struct(ctypes.Structure): # struct xsave_hdr_struct {
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("xstate_bv", ctypes.c_ulonglong), # u64 xstate_bv;
|
("xstate_bv", ctypes.c_ulonglong
|
||||||
("reserved1", ctypes.c_ulonglong*2), # u64 reserved1[2];
|
), # u64 xstate_bv;
|
||||||
("reserved2", ctypes.c_ulonglong*5) # u64 reserved2[5];
|
("reserved1", ctypes.c_ulonglong *
|
||||||
|
2), # u64 reserved1[2];
|
||||||
|
("reserved2", ctypes.c_ulonglong * 5
|
||||||
|
) # u64 reserved2[5];
|
||||||
] # } __packed;
|
] # } __packed;
|
||||||
|
|
||||||
|
|
||||||
class i387_fxsave_struct(ctypes.Structure): # struct i387_fxsave_struct {
|
class i387_fxsave_struct(ctypes.Structure): # struct i387_fxsave_struct {
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("cwd", ctypes.c_ushort), # u16 cwd; /* Control Word */
|
(
|
||||||
("swd", ctypes.c_ushort), # u16 swd; /* Status Word */
|
"cwd", ctypes.c_ushort
|
||||||
("twd", ctypes.c_ushort), # u16 twd; /* Tag Word */
|
), # u16 cwd; /* Control Word */
|
||||||
("fop", ctypes.c_ushort), # u16 fop; /* Last Instruction Opcode */
|
(
|
||||||
|
"swd", ctypes.c_ushort
|
||||||
|
), # u16 swd; /* Status Word */
|
||||||
|
(
|
||||||
|
"twd", ctypes.c_ushort
|
||||||
|
), # u16 twd; /* Tag Word */
|
||||||
|
(
|
||||||
|
"fop", ctypes.c_ushort
|
||||||
|
), # u16 fop; /* Last Instruction Opcode */
|
||||||
# union {
|
# union {
|
||||||
# struct {
|
# struct {
|
||||||
("rip", ctypes.c_ulonglong), # u64 rip; /* Instruction Pointer */
|
(
|
||||||
("rdp", ctypes.c_ulonglong), # u64 rdp; /* Data Pointer */
|
"rip", ctypes.c_ulonglong
|
||||||
|
), # u64 rip; /* Instruction Pointer */
|
||||||
|
(
|
||||||
|
"rdp", ctypes.c_ulonglong
|
||||||
|
), # u64 rdp; /* Data Pointer */
|
||||||
# };
|
# };
|
||||||
# struct {
|
# struct {
|
||||||
# u32 fip; /* FPU IP Offset */
|
# u32 fip; /* FPU IP Offset */
|
||||||
@ -499,19 +648,27 @@ class i387_fxsave_struct(ctypes.Structure): # struct i387_fxsave_struct {
|
|||||||
# u32 fos; /* FPU Operand Selector */
|
# u32 fos; /* FPU Operand Selector */
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
("mxcsr", ctypes.c_uint), # u32 mxcsr; /* MXCSR Register State */
|
(
|
||||||
("mxcsr_mask", ctypes.c_uint), # u32 mxcsr_mask; /* MXCSR Mask */
|
"mxcsr", ctypes.c_uint
|
||||||
|
), # u32 mxcsr; /* MXCSR Register State */
|
||||||
|
(
|
||||||
|
"mxcsr_mask", ctypes.c_uint
|
||||||
|
), # u32 mxcsr_mask; /* MXCSR Mask */
|
||||||
#
|
#
|
||||||
# /* 8*16 bytes for each FP-reg = 128 bytes */
|
# /* 8*16 bytes for each FP-reg = 128 bytes */
|
||||||
("st_space", ctypes.c_uint*32), # u32 st_space[32];
|
("st_space", ctypes.c_uint * 32
|
||||||
|
), # u32 st_space[32];
|
||||||
#
|
#
|
||||||
# /* 16*16 bytes for each XMM-reg = 256 bytes */
|
# /* 16*16 bytes for each XMM-reg = 256 bytes */
|
||||||
("xmm_space", ctypes.c_uint*64), # u32 xmm_space[64];
|
("xmm_space", ctypes.c_uint * 64
|
||||||
|
), # u32 xmm_space[64];
|
||||||
#
|
#
|
||||||
("padding", ctypes.c_uint*12), # u32 padding[12];
|
("padding", ctypes.c_uint * 12
|
||||||
|
), # u32 padding[12];
|
||||||
#
|
#
|
||||||
# union {
|
# union {
|
||||||
("padding1", ctypes.c_uint*12) # u32 padding1[12];
|
("padding1", ctypes.c_uint * 12
|
||||||
|
) # u32 padding1[12];
|
||||||
# u32 sw_reserved[12];
|
# u32 sw_reserved[12];
|
||||||
# };
|
# };
|
||||||
#
|
#
|
||||||
@ -520,7 +677,9 @@ class i387_fxsave_struct(ctypes.Structure): # struct i387_fxsave_struct {
|
|||||||
|
|
||||||
class elf_xsave_struct(ctypes.Structure): # struct xsave_struct {
|
class elf_xsave_struct(ctypes.Structure): # struct xsave_struct {
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("i387", i387_fxsave_struct), # struct i387_fxsave_struct i387;
|
("i387",
|
||||||
("xsave_hdr", xsave_hdr_struct), # struct xsave_hdr_struct xsave_hdr;
|
i387_fxsave_struct), # struct i387_fxsave_struct i387;
|
||||||
|
("xsave_hdr", xsave_hdr_struct
|
||||||
|
), # struct xsave_hdr_struct xsave_hdr;
|
||||||
("ymmh", ymmh_struct) # struct ymmh_struct ymmh;
|
("ymmh", ymmh_struct) # struct ymmh_struct ymmh;
|
||||||
] # } __aligned(FP_MIN_ALIGN_BYTES) __packed;
|
] # } __aligned(FP_MIN_ALIGN_BYTES) __packed;
|
||||||
|
136
lib/py/cli.py
136
lib/py/cli.py
@ -6,21 +6,25 @@ import os
|
|||||||
|
|
||||||
import pycriu
|
import pycriu
|
||||||
|
|
||||||
|
|
||||||
def inf(opts):
|
def inf(opts):
|
||||||
if opts['in']:
|
if opts['in']:
|
||||||
return open(opts['in'], 'rb')
|
return open(opts['in'], 'rb')
|
||||||
else:
|
else:
|
||||||
return sys.stdin
|
return sys.stdin
|
||||||
|
|
||||||
|
|
||||||
def outf(opts):
|
def outf(opts):
|
||||||
if opts['out']:
|
if opts['out']:
|
||||||
return open(opts['out'], 'w+')
|
return open(opts['out'], 'w+')
|
||||||
else:
|
else:
|
||||||
return sys.stdout
|
return sys.stdout
|
||||||
|
|
||||||
|
|
||||||
def dinf(opts, name):
|
def dinf(opts, name):
|
||||||
return open(os.path.join(opts['dir'], name))
|
return open(os.path.join(opts['dir'], name))
|
||||||
|
|
||||||
|
|
||||||
def decode(opts):
|
def decode(opts):
|
||||||
indent = None
|
indent = None
|
||||||
|
|
||||||
@ -40,21 +44,27 @@ def decode(opts):
|
|||||||
if f == sys.stdout:
|
if f == sys.stdout:
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
|
|
||||||
|
|
||||||
def encode(opts):
|
def encode(opts):
|
||||||
img = json.load(inf(opts))
|
img = json.load(inf(opts))
|
||||||
pycriu.images.dump(img, outf(opts))
|
pycriu.images.dump(img, outf(opts))
|
||||||
|
|
||||||
|
|
||||||
def info(opts):
|
def info(opts):
|
||||||
infs = pycriu.images.info(inf(opts))
|
infs = pycriu.images.info(inf(opts))
|
||||||
json.dump(infs, sys.stdout, indent=4)
|
json.dump(infs, sys.stdout, indent=4)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
def get_task_id(p, val):
|
def get_task_id(p, val):
|
||||||
return p[val] if val in p else p['ns_' + val][0]
|
return p[val] if val in p else p['ns_' + val][0]
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Explorers
|
# Explorers
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class ps_item:
|
class ps_item:
|
||||||
def __init__(self, p, core):
|
def __init__(self, p, core):
|
||||||
self.pid = get_task_id(p, 'pid')
|
self.pid = get_task_id(p, 'pid')
|
||||||
@ -63,17 +73,21 @@ class ps_item:
|
|||||||
self.core = core
|
self.core = core
|
||||||
self.kids = []
|
self.kids = []
|
||||||
|
|
||||||
|
|
||||||
def show_ps(p, opts, depth=0):
|
def show_ps(p, opts, depth=0):
|
||||||
print("%7d%7d%7d %s%s" % (p.pid, get_task_id(p.p, 'pgid'), get_task_id(p.p, 'sid'),
|
print("%7d%7d%7d %s%s" %
|
||||||
' ' * (4 * depth), p.core['tc']['comm']))
|
(p.pid, get_task_id(p.p, 'pgid'), get_task_id(p.p, 'sid'), ' ' *
|
||||||
|
(4 * depth), p.core['tc']['comm']))
|
||||||
for kid in p.kids:
|
for kid in p.kids:
|
||||||
show_ps(kid, opts, depth + 1)
|
show_ps(kid, opts, depth + 1)
|
||||||
|
|
||||||
|
|
||||||
def explore_ps(opts):
|
def explore_ps(opts):
|
||||||
pss = {}
|
pss = {}
|
||||||
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
||||||
for p in ps_img['entries']:
|
for p in ps_img['entries']:
|
||||||
core = pycriu.images.load(dinf(opts, 'core-%d.img' % get_task_id(p, 'pid')))
|
core = pycriu.images.load(
|
||||||
|
dinf(opts, 'core-%d.img' % get_task_id(p, 'pid')))
|
||||||
ps = ps_item(p, core['entries'][0])
|
ps = ps_item(p, core['entries'][0])
|
||||||
pss[ps.pid] = ps
|
pss[ps.pid] = ps
|
||||||
|
|
||||||
@ -91,8 +105,10 @@ def explore_ps(opts):
|
|||||||
print("%7s%7s%7s %s" % ('PID', 'PGID', 'SID', 'COMM'))
|
print("%7s%7s%7s %s" % ('PID', 'PGID', 'SID', 'COMM'))
|
||||||
show_ps(psr, opts)
|
show_ps(psr, opts)
|
||||||
|
|
||||||
|
|
||||||
files_img = None
|
files_img = None
|
||||||
|
|
||||||
|
|
||||||
def ftype_find_in_files(opts, ft, fid):
|
def ftype_find_in_files(opts, ft, fid):
|
||||||
global files_img
|
global files_img
|
||||||
|
|
||||||
@ -124,14 +140,17 @@ def ftype_find_in_image(opts, ft, fid, img):
|
|||||||
return f
|
return f
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def ftype_reg(opts, ft, fid):
|
def ftype_reg(opts, ft, fid):
|
||||||
rf = ftype_find_in_image(opts, ft, fid, 'reg-files.img')
|
rf = ftype_find_in_image(opts, ft, fid, 'reg-files.img')
|
||||||
return rf and rf['name'] or 'unknown path'
|
return rf and rf['name'] or 'unknown path'
|
||||||
|
|
||||||
|
|
||||||
def ftype_pipe(opts, ft, fid):
|
def ftype_pipe(opts, ft, fid):
|
||||||
p = ftype_find_in_image(opts, ft, fid, 'pipes.img')
|
p = ftype_find_in_image(opts, ft, fid, 'pipes.img')
|
||||||
return p and 'pipe[%d]' % p['pipe_id'] or 'pipe[?]'
|
return p and 'pipe[%d]' % p['pipe_id'] or 'pipe[?]'
|
||||||
|
|
||||||
|
|
||||||
def ftype_unix(opts, ft, fid):
|
def ftype_unix(opts, ft, fid):
|
||||||
ux = ftype_find_in_image(opts, ft, fid, 'unixsk.img')
|
ux = ftype_find_in_image(opts, ft, fid, 'unixsk.img')
|
||||||
if not ux:
|
if not ux:
|
||||||
@ -140,17 +159,33 @@ def ftype_unix(opts, ft, fid):
|
|||||||
n = ux['name'] and ' %s' % ux['name'] or ''
|
n = ux['name'] and ' %s' % ux['name'] or ''
|
||||||
return 'unix[%d (%d)%s]' % (ux['ino'], ux['peer'], n)
|
return 'unix[%d (%d)%s]' % (ux['ino'], ux['peer'], n)
|
||||||
|
|
||||||
|
|
||||||
file_types = {
|
file_types = {
|
||||||
'REG': {'get': ftype_reg, 'img': None, 'field': 'reg'},
|
'REG': {
|
||||||
'PIPE': {'get': ftype_pipe, 'img': None, 'field': 'pipe'},
|
'get': ftype_reg,
|
||||||
'UNIXSK': {'get': ftype_unix, 'img': None, 'field': 'usk'},
|
'img': None,
|
||||||
|
'field': 'reg'
|
||||||
|
},
|
||||||
|
'PIPE': {
|
||||||
|
'get': ftype_pipe,
|
||||||
|
'img': None,
|
||||||
|
'field': 'pipe'
|
||||||
|
},
|
||||||
|
'UNIXSK': {
|
||||||
|
'get': ftype_unix,
|
||||||
|
'img': None,
|
||||||
|
'field': 'usk'
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def ftype_gen(opts, ft, fid):
|
def ftype_gen(opts, ft, fid):
|
||||||
return '%s.%d' % (ft['typ'], fid)
|
return '%s.%d' % (ft['typ'], fid)
|
||||||
|
|
||||||
|
|
||||||
files_cache = {}
|
files_cache = {}
|
||||||
|
|
||||||
|
|
||||||
def get_file_str(opts, fd):
|
def get_file_str(opts, fd):
|
||||||
key = (fd['type'], fd['id'])
|
key = (fd['type'], fd['id'])
|
||||||
f = files_cache.get(key, None)
|
f = files_cache.get(key, None)
|
||||||
@ -161,6 +196,7 @@ def get_file_str(opts, fd):
|
|||||||
|
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
def explore_fds(opts):
|
def explore_fds(opts):
|
||||||
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
||||||
for p in ps_img['entries']:
|
for p in ps_img['entries']:
|
||||||
@ -174,8 +210,16 @@ def explore_fds(opts):
|
|||||||
print("\t%7d: %s" % (fd['fd'], get_file_str(opts, fd)))
|
print("\t%7d: %s" % (fd['fd'], get_file_str(opts, fd)))
|
||||||
|
|
||||||
fdi = pycriu.images.load(dinf(opts, 'fs-%d.img' % pid))['entries'][0]
|
fdi = pycriu.images.load(dinf(opts, 'fs-%d.img' % pid))['entries'][0]
|
||||||
print("\t%7s: %s" % ('cwd', get_file_str(opts, {'type': 'REG', 'id': fdi['cwd_id']})))
|
print("\t%7s: %s" %
|
||||||
print("\t%7s: %s" % ('root', get_file_str(opts, {'type': 'REG', 'id': fdi['root_id']})))
|
('cwd', get_file_str(opts, {
|
||||||
|
'type': 'REG',
|
||||||
|
'id': fdi['cwd_id']
|
||||||
|
})))
|
||||||
|
print("\t%7s: %s" %
|
||||||
|
('root', get_file_str(opts, {
|
||||||
|
'type': 'REG',
|
||||||
|
'id': fdi['root_id']
|
||||||
|
})))
|
||||||
|
|
||||||
|
|
||||||
class vma_id:
|
class vma_id:
|
||||||
@ -192,6 +236,7 @@ class vma_id:
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def explore_mems(opts):
|
def explore_mems(opts):
|
||||||
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
||||||
vids = vma_id()
|
vids = vma_id()
|
||||||
@ -200,7 +245,11 @@ def explore_mems(opts):
|
|||||||
mmi = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]
|
mmi = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]
|
||||||
|
|
||||||
print("%d" % pid)
|
print("%d" % pid)
|
||||||
print("\t%-36s %s" % ('exe', get_file_str(opts, {'type': 'REG', 'id': mmi['exe_file_id']})))
|
print("\t%-36s %s" % ('exe',
|
||||||
|
get_file_str(opts, {
|
||||||
|
'type': 'REG',
|
||||||
|
'id': mmi['exe_file_id']
|
||||||
|
})))
|
||||||
|
|
||||||
for vma in mmi['vmas']:
|
for vma in mmi['vmas']:
|
||||||
st = vma['status']
|
st = vma['status']
|
||||||
@ -211,7 +260,10 @@ def explore_mems(opts):
|
|||||||
elif st & (1 << 11):
|
elif st & (1 << 11):
|
||||||
fn = ' ' + 'packet[%lx]' % vids.get(vma['shmid'])
|
fn = ' ' + 'packet[%lx]' % vids.get(vma['shmid'])
|
||||||
elif st & ((1 << 6) | (1 << 7)):
|
elif st & ((1 << 6) | (1 << 7)):
|
||||||
fn = ' ' + get_file_str(opts, {'type': 'REG', 'id': vma['shmid']})
|
fn = ' ' + get_file_str(opts, {
|
||||||
|
'type': 'REG',
|
||||||
|
'id': vma['shmid']
|
||||||
|
})
|
||||||
if vma['pgoff']:
|
if vma['pgoff']:
|
||||||
fn += ' + %#lx' % vma['pgoff']
|
fn += ' + %#lx' % vma['pgoff']
|
||||||
if st & (1 << 7):
|
if st & (1 << 7):
|
||||||
@ -242,7 +294,8 @@ def explore_rss(opts):
|
|||||||
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
|
||||||
for p in ps_img['entries']:
|
for p in ps_img['entries']:
|
||||||
pid = get_task_id(p, 'pid')
|
pid = get_task_id(p, 'pid')
|
||||||
vmas = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]['vmas']
|
vmas = pycriu.images.load(dinf(opts, 'mm-%d.img' %
|
||||||
|
pid))['entries'][0]['vmas']
|
||||||
pms = pycriu.images.load(dinf(opts, 'pagemap-%d.img' % pid))['entries']
|
pms = pycriu.images.load(dinf(opts, 'pagemap-%d.img' % pid))['entries']
|
||||||
|
|
||||||
print("%d" % pid)
|
print("%d" % pid)
|
||||||
@ -260,9 +313,13 @@ def explore_rss(opts):
|
|||||||
if vmi == pvmi:
|
if vmi == pvmi:
|
||||||
vstr += ' ~'
|
vstr += ' ~'
|
||||||
else:
|
else:
|
||||||
vstr += ' %08lx / %-8d' % (vma['start'], (vma['end'] - vma['start'])>>12)
|
vstr += ' %08lx / %-8d' % (
|
||||||
|
vma['start'], (vma['end'] - vma['start']) >> 12)
|
||||||
if vma['status'] & ((1 << 6) | (1 << 7)):
|
if vma['status'] & ((1 << 6) | (1 << 7)):
|
||||||
vstr += ' ' + get_file_str(opts, {'type': 'REG', 'id': vma['shmid']})
|
vstr += ' ' + get_file_str(opts, {
|
||||||
|
'type': 'REG',
|
||||||
|
'id': vma['shmid']
|
||||||
|
})
|
||||||
pvmi = vmi
|
pvmi = vmi
|
||||||
vstr += '\n\t%23s' % ''
|
vstr += '\n\t%23s' % ''
|
||||||
vmi += 1
|
vmi += 1
|
||||||
@ -272,47 +329,59 @@ def explore_rss(opts):
|
|||||||
print('%-24s%s' % (pstr, vstr))
|
print('%-24s%s' % (pstr, vstr))
|
||||||
|
|
||||||
|
|
||||||
|
explorers = {
|
||||||
|
'ps': explore_ps,
|
||||||
|
'fds': explore_fds,
|
||||||
|
'mems': explore_mems,
|
||||||
|
'rss': explore_rss
|
||||||
|
}
|
||||||
|
|
||||||
explorers = { 'ps': explore_ps, 'fds': explore_fds, 'mems': explore_mems, 'rss': explore_rss }
|
|
||||||
|
|
||||||
def explore(opts):
|
def explore(opts):
|
||||||
explorers[opts['what']](opts)
|
explorers[opts['what']](opts)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
desc = 'CRiu Image Tool'
|
desc = 'CRiu Image Tool'
|
||||||
parser = argparse.ArgumentParser(description=desc,
|
parser = argparse.ArgumentParser(
|
||||||
formatter_class=argparse.RawTextHelpFormatter)
|
description=desc, formatter_class=argparse.RawTextHelpFormatter)
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(help='Use crit CMD --help for command-specific help')
|
subparsers = parser.add_subparsers(
|
||||||
|
help='Use crit CMD --help for command-specific help')
|
||||||
|
|
||||||
# Decode
|
# Decode
|
||||||
decode_parser = subparsers.add_parser('decode',
|
decode_parser = subparsers.add_parser(
|
||||||
help = 'convert criu image from binary type to json')
|
'decode', help='convert criu image from binary type to json')
|
||||||
decode_parser.add_argument('--pretty',
|
decode_parser.add_argument(
|
||||||
help = 'Multiline with indents and some numerical fields in field-specific format',
|
'--pretty',
|
||||||
|
help=
|
||||||
|
'Multiline with indents and some numerical fields in field-specific format',
|
||||||
action='store_true')
|
action='store_true')
|
||||||
decode_parser.add_argument('-i',
|
decode_parser.add_argument(
|
||||||
|
'-i',
|
||||||
'--in',
|
'--in',
|
||||||
help='criu image in binary format to be decoded (stdin by default)')
|
help='criu image in binary format to be decoded (stdin by default)')
|
||||||
decode_parser.add_argument('-o',
|
decode_parser.add_argument(
|
||||||
|
'-o',
|
||||||
'--out',
|
'--out',
|
||||||
help='where to put criu image in json format (stdout by default)')
|
help='where to put criu image in json format (stdout by default)')
|
||||||
decode_parser.set_defaults(func=decode, nopl=False)
|
decode_parser.set_defaults(func=decode, nopl=False)
|
||||||
|
|
||||||
# Encode
|
# Encode
|
||||||
encode_parser = subparsers.add_parser('encode',
|
encode_parser = subparsers.add_parser(
|
||||||
help = 'convert criu image from json type to binary')
|
'encode', help='convert criu image from json type to binary')
|
||||||
encode_parser.add_argument('-i',
|
encode_parser.add_argument(
|
||||||
|
'-i',
|
||||||
'--in',
|
'--in',
|
||||||
help='criu image in json format to be encoded (stdin by default)')
|
help='criu image in json format to be encoded (stdin by default)')
|
||||||
encode_parser.add_argument('-o',
|
encode_parser.add_argument(
|
||||||
|
'-o',
|
||||||
'--out',
|
'--out',
|
||||||
help='where to put criu image in binary format (stdout by default)')
|
help='where to put criu image in binary format (stdout by default)')
|
||||||
encode_parser.set_defaults(func=encode)
|
encode_parser.set_defaults(func=encode)
|
||||||
|
|
||||||
# Info
|
# Info
|
||||||
info_parser = subparsers.add_parser('info',
|
info_parser = subparsers.add_parser('info', help='show info about image')
|
||||||
help = 'show info about image')
|
|
||||||
info_parser.add_argument("in")
|
info_parser.add_argument("in")
|
||||||
info_parser.set_defaults(func=info)
|
info_parser.set_defaults(func=info)
|
||||||
|
|
||||||
@ -323,10 +392,12 @@ def main():
|
|||||||
x_parser.set_defaults(func=explore)
|
x_parser.set_defaults(func=explore)
|
||||||
|
|
||||||
# Show
|
# Show
|
||||||
show_parser = subparsers.add_parser('show',
|
show_parser = subparsers.add_parser(
|
||||||
help = "convert criu image from binary to human-readable json")
|
'show', help="convert criu image from binary to human-readable json")
|
||||||
show_parser.add_argument("in")
|
show_parser.add_argument("in")
|
||||||
show_parser.add_argument('--nopl', help = 'do not show entry payload (if exists)', action = 'store_true')
|
show_parser.add_argument('--nopl',
|
||||||
|
help='do not show entry payload (if exists)',
|
||||||
|
action='store_true')
|
||||||
show_parser.set_defaults(func=decode, pretty=True, out=None)
|
show_parser.set_defaults(func=decode, pretty=True, out=None)
|
||||||
|
|
||||||
opts = vars(parser.parse_args())
|
opts = vars(parser.parse_args())
|
||||||
@ -338,5 +409,6 @@ def main():
|
|||||||
|
|
||||||
opts["func"](opts)
|
opts["func"](opts)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -8,6 +8,7 @@ import struct
|
|||||||
|
|
||||||
import pycriu.rpc_pb2 as rpc
|
import pycriu.rpc_pb2 as rpc
|
||||||
|
|
||||||
|
|
||||||
class _criu_comm:
|
class _criu_comm:
|
||||||
"""
|
"""
|
||||||
Base class for communication classes.
|
Base class for communication classes.
|
||||||
@ -37,6 +38,7 @@ class _criu_comm_sk(_criu_comm):
|
|||||||
"""
|
"""
|
||||||
Communication class for unix socket.
|
Communication class for unix socket.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sk_path):
|
def __init__(self, sk_path):
|
||||||
self.comm_type = self.COMM_SK
|
self.comm_type = self.COMM_SK
|
||||||
self.comm = sk_path
|
self.comm = sk_path
|
||||||
@ -55,22 +57,26 @@ class _criu_comm_fd(_criu_comm):
|
|||||||
"""
|
"""
|
||||||
Communication class for file descriptor.
|
Communication class for file descriptor.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, fd):
|
def __init__(self, fd):
|
||||||
self.comm_type = self.COMM_FD
|
self.comm_type = self.COMM_FD
|
||||||
self.comm = fd
|
self.comm = fd
|
||||||
|
|
||||||
def connect(self, daemon):
|
def connect(self, daemon):
|
||||||
self.sk = socket.fromfd(self.comm, socket.AF_UNIX, socket.SOCK_SEQPACKET)
|
self.sk = socket.fromfd(self.comm, socket.AF_UNIX,
|
||||||
|
socket.SOCK_SEQPACKET)
|
||||||
|
|
||||||
return self.sk
|
return self.sk
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
self.sk.close()
|
self.sk.close()
|
||||||
|
|
||||||
|
|
||||||
class _criu_comm_bin(_criu_comm):
|
class _criu_comm_bin(_criu_comm):
|
||||||
"""
|
"""
|
||||||
Communication class for binary.
|
Communication class for binary.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bin_path):
|
def __init__(self, bin_path):
|
||||||
self.comm_type = self.COMM_BIN
|
self.comm_type = self.COMM_BIN
|
||||||
self.comm = bin_path
|
self.comm = bin_path
|
||||||
@ -90,13 +96,16 @@ class _criu_comm_bin(_criu_comm):
|
|||||||
p = os.fork()
|
p = os.fork()
|
||||||
|
|
||||||
if p == 0:
|
if p == 0:
|
||||||
|
|
||||||
def exec_criu():
|
def exec_criu():
|
||||||
os.close(0)
|
os.close(0)
|
||||||
os.close(1)
|
os.close(1)
|
||||||
os.close(2)
|
os.close(2)
|
||||||
|
|
||||||
css[0].send(struct.pack('i', os.getpid()))
|
css[0].send(struct.pack('i', os.getpid()))
|
||||||
os.execv(self.comm, [self.comm, 'swrk', "%d" % css[0].fileno()])
|
os.execv(self.comm,
|
||||||
|
[self.comm, 'swrk',
|
||||||
|
"%d" % css[0].fileno()])
|
||||||
os._exit(1)
|
os._exit(1)
|
||||||
|
|
||||||
if daemon:
|
if daemon:
|
||||||
@ -143,9 +152,11 @@ class CRIUExceptionInternal(CRIUException):
|
|||||||
"""
|
"""
|
||||||
Exception class for handling and storing internal errors.
|
Exception class for handling and storing internal errors.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, typ, s):
|
def __init__(self, typ, s):
|
||||||
self.typ = typ
|
self.typ = typ
|
||||||
self._str = "%s failed with internal error: %s" % (rpc.criu_req_type.Name(self.typ), s)
|
self._str = "%s failed with internal error: %s" % (
|
||||||
|
rpc.criu_req_type.Name(self.typ), s)
|
||||||
|
|
||||||
|
|
||||||
class CRIUExceptionExternal(CRIUException):
|
class CRIUExceptionExternal(CRIUException):
|
||||||
|
@ -57,14 +57,17 @@ sizeof_u16 = 2
|
|||||||
sizeof_u32 = 4
|
sizeof_u32 = 4
|
||||||
sizeof_u64 = 8
|
sizeof_u64 = 8
|
||||||
|
|
||||||
|
|
||||||
# A helper for rounding
|
# A helper for rounding
|
||||||
def round_up(x, y):
|
def round_up(x, y):
|
||||||
return (((x - 1) | (y - 1)) + 1)
|
return (((x - 1) | (y - 1)) + 1)
|
||||||
|
|
||||||
|
|
||||||
class MagicException(Exception):
|
class MagicException(Exception):
|
||||||
def __init__(self, magic):
|
def __init__(self, magic):
|
||||||
self.magic = magic
|
self.magic = magic
|
||||||
|
|
||||||
|
|
||||||
# Generic class to handle loading/dumping criu images entries from/to bin
|
# Generic class to handle loading/dumping criu images entries from/to bin
|
||||||
# format to/from dict(json).
|
# format to/from dict(json).
|
||||||
class entry_handler:
|
class entry_handler:
|
||||||
@ -72,6 +75,7 @@ class entry_handler:
|
|||||||
Generic class to handle loading/dumping criu images
|
Generic class to handle loading/dumping criu images
|
||||||
entries from/to bin format to/from dict(json).
|
entries from/to bin format to/from dict(json).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, payload, extra_handler=None):
|
def __init__(self, payload, extra_handler=None):
|
||||||
"""
|
"""
|
||||||
Sets payload class and extra handler class.
|
Sets payload class and extra handler class.
|
||||||
@ -102,6 +106,7 @@ class entry_handler:
|
|||||||
# Read extra
|
# Read extra
|
||||||
if self.extra_handler:
|
if self.extra_handler:
|
||||||
if no_payload:
|
if no_payload:
|
||||||
|
|
||||||
def human_readable(num):
|
def human_readable(num):
|
||||||
for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
|
for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
|
||||||
if num < 1024.0:
|
if num < 1024.0:
|
||||||
@ -174,6 +179,7 @@ class entry_handler:
|
|||||||
|
|
||||||
return entries
|
return entries
|
||||||
|
|
||||||
|
|
||||||
# Special handler for pagemap.img
|
# Special handler for pagemap.img
|
||||||
class pagemap_handler:
|
class pagemap_handler:
|
||||||
"""
|
"""
|
||||||
@ -181,6 +187,7 @@ class pagemap_handler:
|
|||||||
that it has a header of pagemap_head type followed by entries
|
that it has a header of pagemap_head type followed by entries
|
||||||
of pagemap_entry type.
|
of pagemap_entry type.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def load(self, f, pretty=False, no_payload=False):
|
def load(self, f, pretty=False, no_payload=False):
|
||||||
entries = []
|
entries = []
|
||||||
|
|
||||||
@ -220,6 +227,7 @@ class pagemap_handler:
|
|||||||
def count(self, f):
|
def count(self, f):
|
||||||
return entry_handler(None).count(f) - 1
|
return entry_handler(None).count(f) - 1
|
||||||
|
|
||||||
|
|
||||||
# Special handler for ghost-file.img
|
# Special handler for ghost-file.img
|
||||||
class ghost_file_handler:
|
class ghost_file_handler:
|
||||||
def load(self, f, pretty=False, no_payload=False):
|
def load(self, f, pretty=False, no_payload=False):
|
||||||
@ -306,6 +314,7 @@ class pipes_data_extra_handler:
|
|||||||
f.seek(pload.bytes, os.SEEK_CUR)
|
f.seek(pload.bytes, os.SEEK_CUR)
|
||||||
return pload.bytes
|
return pload.bytes
|
||||||
|
|
||||||
|
|
||||||
class sk_queues_extra_handler:
|
class sk_queues_extra_handler:
|
||||||
def load(self, f, pload):
|
def load(self, f, pload):
|
||||||
size = pload.length
|
size = pload.length
|
||||||
@ -344,6 +353,7 @@ class tcp_stream_extra_handler:
|
|||||||
f.seek(0, os.SEEK_END)
|
f.seek(0, os.SEEK_END)
|
||||||
return pbuff.inq_len + pbuff.outq_len
|
return pbuff.inq_len + pbuff.outq_len
|
||||||
|
|
||||||
|
|
||||||
class ipc_sem_set_handler:
|
class ipc_sem_set_handler:
|
||||||
def load(self, f, pbuff):
|
def load(self, f, pbuff):
|
||||||
entry = pb2dict.pb2dict(pbuff)
|
entry = pb2dict.pb2dict(pbuff)
|
||||||
@ -375,6 +385,7 @@ class ipc_sem_set_handler:
|
|||||||
f.seek(round_up(size, sizeof_u64), os.SEEK_CUR)
|
f.seek(round_up(size, sizeof_u64), os.SEEK_CUR)
|
||||||
return size
|
return size
|
||||||
|
|
||||||
|
|
||||||
class ipc_msg_queue_handler:
|
class ipc_msg_queue_handler:
|
||||||
def load(self, f, pbuff):
|
def load(self, f, pbuff):
|
||||||
entry = pb2dict.pb2dict(pbuff)
|
entry = pb2dict.pb2dict(pbuff)
|
||||||
@ -423,6 +434,7 @@ class ipc_msg_queue_handler:
|
|||||||
|
|
||||||
return pl_len
|
return pl_len
|
||||||
|
|
||||||
|
|
||||||
class ipc_shm_handler:
|
class ipc_shm_handler:
|
||||||
def load(self, f, pbuff):
|
def load(self, f, pbuff):
|
||||||
entry = pb2dict.pb2dict(pbuff)
|
entry = pb2dict.pb2dict(pbuff)
|
||||||
@ -459,7 +471,8 @@ handlers = {
|
|||||||
'GHOST_FILE': ghost_file_handler(),
|
'GHOST_FILE': ghost_file_handler(),
|
||||||
'MM': entry_handler(pb.mm_entry),
|
'MM': entry_handler(pb.mm_entry),
|
||||||
'CGROUP': entry_handler(pb.cgroup_entry),
|
'CGROUP': entry_handler(pb.cgroup_entry),
|
||||||
'TCP_STREAM' : entry_handler(pb.tcp_stream_entry, tcp_stream_extra_handler()),
|
'TCP_STREAM': entry_handler(pb.tcp_stream_entry,
|
||||||
|
tcp_stream_extra_handler()),
|
||||||
'STATS': entry_handler(pb.stats_entry),
|
'STATS': entry_handler(pb.stats_entry),
|
||||||
'PAGEMAP': pagemap_handler(), # Special one
|
'PAGEMAP': pagemap_handler(), # Special one
|
||||||
'PSTREE': entry_handler(pb.pstree_entry),
|
'PSTREE': entry_handler(pb.pstree_entry),
|
||||||
@ -496,7 +509,8 @@ handlers = {
|
|||||||
'ITIMERS': entry_handler(pb.itimer_entry),
|
'ITIMERS': entry_handler(pb.itimer_entry),
|
||||||
'POSIX_TIMERS': entry_handler(pb.posix_timer_entry),
|
'POSIX_TIMERS': entry_handler(pb.posix_timer_entry),
|
||||||
'NETDEV': entry_handler(pb.net_device_entry),
|
'NETDEV': entry_handler(pb.net_device_entry),
|
||||||
'PIPES_DATA' : entry_handler(pb.pipe_data_entry, pipes_data_extra_handler()),
|
'PIPES_DATA': entry_handler(pb.pipe_data_entry,
|
||||||
|
pipes_data_extra_handler()),
|
||||||
'FIFO_DATA': entry_handler(pb.pipe_data_entry, pipes_data_extra_handler()),
|
'FIFO_DATA': entry_handler(pb.pipe_data_entry, pipes_data_extra_handler()),
|
||||||
'SK_QUEUES': entry_handler(pb.sk_packet_entry, sk_queues_extra_handler()),
|
'SK_QUEUES': entry_handler(pb.sk_packet_entry, sk_queues_extra_handler()),
|
||||||
'IPCNS_SHM': entry_handler(pb.ipc_shm_entry, ipc_shm_handler()),
|
'IPCNS_SHM': entry_handler(pb.ipc_shm_entry, ipc_shm_handler()),
|
||||||
@ -510,10 +524,12 @@ handlers = {
|
|||||||
'CPUINFO': entry_handler(pb.cpuinfo_entry),
|
'CPUINFO': entry_handler(pb.cpuinfo_entry),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __rhandler(f):
|
def __rhandler(f):
|
||||||
# Images v1.1 NOTE: First read "first" magic.
|
# Images v1.1 NOTE: First read "first" magic.
|
||||||
img_magic, = struct.unpack('i', f.read(4))
|
img_magic, = struct.unpack('i', f.read(4))
|
||||||
if img_magic in (magic.by_name['IMG_COMMON'], magic.by_name['IMG_SERVICE']):
|
if img_magic in (magic.by_name['IMG_COMMON'],
|
||||||
|
magic.by_name['IMG_SERVICE']):
|
||||||
img_magic, = struct.unpack('i', f.read(4))
|
img_magic, = struct.unpack('i', f.read(4))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -528,6 +544,7 @@ def __rhandler(f):
|
|||||||
|
|
||||||
return m, handler
|
return m, handler
|
||||||
|
|
||||||
|
|
||||||
def load(f, pretty=False, no_payload=False):
|
def load(f, pretty=False, no_payload=False):
|
||||||
"""
|
"""
|
||||||
Convert criu image from binary format to dict(json).
|
Convert criu image from binary format to dict(json).
|
||||||
@ -543,6 +560,7 @@ def load(f, pretty = False, no_payload = False):
|
|||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
|
||||||
def info(f):
|
def info(f):
|
||||||
res = {}
|
res = {}
|
||||||
|
|
||||||
@ -553,6 +571,7 @@ def info(f):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def loads(s, pretty=False):
|
def loads(s, pretty=False):
|
||||||
"""
|
"""
|
||||||
Same as load(), but takes a string.
|
Same as load(), but takes a string.
|
||||||
@ -560,6 +579,7 @@ def loads(s, pretty = False):
|
|||||||
f = io.BytesIO(s)
|
f = io.BytesIO(s)
|
||||||
return load(f, pretty)
|
return load(f, pretty)
|
||||||
|
|
||||||
|
|
||||||
def dump(img, f):
|
def dump(img, f):
|
||||||
"""
|
"""
|
||||||
Convert criu image from dict(json) format to binary.
|
Convert criu image from dict(json) format to binary.
|
||||||
@ -586,6 +606,7 @@ def dump(img, f):
|
|||||||
|
|
||||||
handler.dump(img['entries'], f)
|
handler.dump(img['entries'], f)
|
||||||
|
|
||||||
|
|
||||||
def dumps(img):
|
def dumps(img):
|
||||||
"""
|
"""
|
||||||
Same as dump(), but takes only an image and returns
|
Same as dump(), but takes only an image and returns
|
||||||
|
@ -29,47 +29,50 @@ if "encodebytes" not in dir(base64):
|
|||||||
# enums to string value too. (i.e. "march : x86_64" is better then
|
# enums to string value too. (i.e. "march : x86_64" is better then
|
||||||
# "march : 1").
|
# "march : 1").
|
||||||
|
|
||||||
|
|
||||||
_basic_cast = {
|
_basic_cast = {
|
||||||
FD.TYPE_FIXED64: int,
|
FD.TYPE_FIXED64: int,
|
||||||
FD.TYPE_FIXED32: int,
|
FD.TYPE_FIXED32: int,
|
||||||
FD.TYPE_SFIXED64: int,
|
FD.TYPE_SFIXED64: int,
|
||||||
FD.TYPE_SFIXED32: int,
|
FD.TYPE_SFIXED32: int,
|
||||||
|
|
||||||
FD.TYPE_INT64: int,
|
FD.TYPE_INT64: int,
|
||||||
FD.TYPE_UINT64: int,
|
FD.TYPE_UINT64: int,
|
||||||
FD.TYPE_SINT64: int,
|
FD.TYPE_SINT64: int,
|
||||||
|
|
||||||
FD.TYPE_INT32: int,
|
FD.TYPE_INT32: int,
|
||||||
FD.TYPE_UINT32: int,
|
FD.TYPE_UINT32: int,
|
||||||
FD.TYPE_SINT32: int,
|
FD.TYPE_SINT32: int,
|
||||||
|
|
||||||
FD.TYPE_BOOL: bool,
|
FD.TYPE_BOOL: bool,
|
||||||
|
|
||||||
FD.TYPE_STRING: str
|
FD.TYPE_STRING: str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _marked_as_hex(field):
|
def _marked_as_hex(field):
|
||||||
return field.GetOptions().Extensions[opts_pb2.criu].hex
|
return field.GetOptions().Extensions[opts_pb2.criu].hex
|
||||||
|
|
||||||
|
|
||||||
def _marked_as_ip(field):
|
def _marked_as_ip(field):
|
||||||
return field.GetOptions().Extensions[opts_pb2.criu].ipadd
|
return field.GetOptions().Extensions[opts_pb2.criu].ipadd
|
||||||
|
|
||||||
|
|
||||||
def _marked_as_flags(field):
|
def _marked_as_flags(field):
|
||||||
return field.GetOptions().Extensions[opts_pb2.criu].flags
|
return field.GetOptions().Extensions[opts_pb2.criu].flags
|
||||||
|
|
||||||
|
|
||||||
def _marked_as_dev(field):
|
def _marked_as_dev(field):
|
||||||
return field.GetOptions().Extensions[opts_pb2.criu].dev
|
return field.GetOptions().Extensions[opts_pb2.criu].dev
|
||||||
|
|
||||||
|
|
||||||
def _marked_as_odev(field):
|
def _marked_as_odev(field):
|
||||||
return field.GetOptions().Extensions[opts_pb2.criu].odev
|
return field.GetOptions().Extensions[opts_pb2.criu].odev
|
||||||
|
|
||||||
|
|
||||||
def _marked_as_dict(field):
|
def _marked_as_dict(field):
|
||||||
return field.GetOptions().Extensions[opts_pb2.criu].dict
|
return field.GetOptions().Extensions[opts_pb2.criu].dict
|
||||||
|
|
||||||
|
|
||||||
def _custom_conv(field):
|
def _custom_conv(field):
|
||||||
return field.GetOptions().Extensions[opts_pb2.criu].conv
|
return field.GetOptions().Extensions[opts_pb2.criu].conv
|
||||||
|
|
||||||
|
|
||||||
mmap_prot_map = [
|
mmap_prot_map = [
|
||||||
('PROT_READ', 0x1),
|
('PROT_READ', 0x1),
|
||||||
('PROT_WRITE', 0x2),
|
('PROT_WRITE', 0x2),
|
||||||
@ -90,17 +93,14 @@ mmap_status_map = [
|
|||||||
('VMA_AREA_VSYSCALL', 1 << 2),
|
('VMA_AREA_VSYSCALL', 1 << 2),
|
||||||
('VMA_AREA_VDSO', 1 << 3),
|
('VMA_AREA_VDSO', 1 << 3),
|
||||||
('VMA_AREA_HEAP', 1 << 5),
|
('VMA_AREA_HEAP', 1 << 5),
|
||||||
|
|
||||||
('VMA_FILE_PRIVATE', 1 << 6),
|
('VMA_FILE_PRIVATE', 1 << 6),
|
||||||
('VMA_FILE_SHARED', 1 << 7),
|
('VMA_FILE_SHARED', 1 << 7),
|
||||||
('VMA_ANON_SHARED', 1 << 8),
|
('VMA_ANON_SHARED', 1 << 8),
|
||||||
('VMA_ANON_PRIVATE', 1 << 9),
|
('VMA_ANON_PRIVATE', 1 << 9),
|
||||||
|
|
||||||
('VMA_AREA_SYSVIPC', 1 << 10),
|
('VMA_AREA_SYSVIPC', 1 << 10),
|
||||||
('VMA_AREA_SOCKET', 1 << 11),
|
('VMA_AREA_SOCKET', 1 << 11),
|
||||||
('VMA_AREA_VVAR', 1 << 12),
|
('VMA_AREA_VVAR', 1 << 12),
|
||||||
('VMA_AREA_AIORING', 1 << 13),
|
('VMA_AREA_AIORING', 1 << 13),
|
||||||
|
|
||||||
('VMA_UNSUPP', 1 << 31),
|
('VMA_UNSUPP', 1 << 31),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -127,21 +127,30 @@ flags_maps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gen_maps = {
|
gen_maps = {
|
||||||
'task_state' : { 1: 'Alive', 3: 'Zombie', 6: 'Stopped' },
|
'task_state': {
|
||||||
|
1: 'Alive',
|
||||||
|
3: 'Zombie',
|
||||||
|
6: 'Stopped'
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_maps = {
|
sk_maps = {
|
||||||
'family' : { 1: 'UNIX',
|
'family': {
|
||||||
|
1: 'UNIX',
|
||||||
2: 'INET',
|
2: 'INET',
|
||||||
10: 'INET6',
|
10: 'INET6',
|
||||||
16: 'NETLINK',
|
16: 'NETLINK',
|
||||||
17: 'PACKET' },
|
17: 'PACKET'
|
||||||
'type' : { 1: 'STREAM',
|
},
|
||||||
|
'type': {
|
||||||
|
1: 'STREAM',
|
||||||
2: 'DGRAM',
|
2: 'DGRAM',
|
||||||
3: 'RAW',
|
3: 'RAW',
|
||||||
5: 'SEQPACKET',
|
5: 'SEQPACKET',
|
||||||
10: 'PACKET' },
|
10: 'PACKET'
|
||||||
'state' : { 1: 'ESTABLISHED',
|
},
|
||||||
|
'state': {
|
||||||
|
1: 'ESTABLISHED',
|
||||||
2: 'SYN_SENT',
|
2: 'SYN_SENT',
|
||||||
3: 'SYN_RECV',
|
3: 'SYN_RECV',
|
||||||
4: 'FIN_WAIT1',
|
4: 'FIN_WAIT1',
|
||||||
@ -150,21 +159,33 @@ sk_maps = {
|
|||||||
7: 'CLOSE',
|
7: 'CLOSE',
|
||||||
8: 'CLOSE_WAIT',
|
8: 'CLOSE_WAIT',
|
||||||
9: 'LAST_ACK',
|
9: 'LAST_ACK',
|
||||||
10: 'LISTEN' },
|
10: 'LISTEN'
|
||||||
'proto' : { 0: 'IP',
|
},
|
||||||
|
'proto': {
|
||||||
|
0: 'IP',
|
||||||
6: 'TCP',
|
6: 'TCP',
|
||||||
17: 'UDP',
|
17: 'UDP',
|
||||||
136: 'UDPLITE' },
|
136: 'UDPLITE'
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_rmaps = { k: {v2:k2 for k2,v2 in list(v.items())} for k,v in list(gen_maps.items()) }
|
gen_rmaps = {
|
||||||
sk_rmaps = { k: {v2:k2 for k2,v2 in list(v.items())} for k,v in list(sk_maps.items()) }
|
k: {v2: k2
|
||||||
|
for k2, v2 in list(v.items())}
|
||||||
|
for k, v in list(gen_maps.items())
|
||||||
|
}
|
||||||
|
sk_rmaps = {
|
||||||
|
k: {v2: k2
|
||||||
|
for k2, v2 in list(v.items())}
|
||||||
|
for k, v in list(sk_maps.items())
|
||||||
|
}
|
||||||
|
|
||||||
dict_maps = {
|
dict_maps = {
|
||||||
'gen': (gen_maps, gen_rmaps),
|
'gen': (gen_maps, gen_rmaps),
|
||||||
'sk': (sk_maps, sk_rmaps),
|
'sk': (sk_maps, sk_rmaps),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def map_flags(value, flags_map):
|
def map_flags(value, flags_map):
|
||||||
bs = [x[0] for x in [x for x in flags_map if value & x[1]]]
|
bs = [x[0] for x in [x for x in flags_map if value & x[1]]]
|
||||||
value &= ~sum([x[1] for x in flags_map])
|
value &= ~sum([x[1] for x in flags_map])
|
||||||
@ -172,20 +193,28 @@ def map_flags(value, flags_map):
|
|||||||
bs.append("0x%x" % value)
|
bs.append("0x%x" % value)
|
||||||
return " | ".join(bs)
|
return " | ".join(bs)
|
||||||
|
|
||||||
|
|
||||||
def unmap_flags(value, flags_map):
|
def unmap_flags(value, flags_map):
|
||||||
if value == '':
|
if value == '':
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
bd = dict(flags_map)
|
bd = dict(flags_map)
|
||||||
return sum([int(str(bd.get(x, x)), 0) for x in [x.strip() for x in value.split('|')]])
|
return sum([
|
||||||
|
int(str(bd.get(x, x)), 0)
|
||||||
|
for x in [x.strip() for x in value.split('|')]
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
kern_minorbits = 20 # This is how kernel encodes dev_t in new format
|
kern_minorbits = 20 # This is how kernel encodes dev_t in new format
|
||||||
|
|
||||||
|
|
||||||
def decode_dev(field, value):
|
def decode_dev(field, value):
|
||||||
if _marked_as_odev(field):
|
if _marked_as_odev(field):
|
||||||
return "%d:%d" % (os.major(value), os.minor(value))
|
return "%d:%d" % (os.major(value), os.minor(value))
|
||||||
else:
|
else:
|
||||||
return "%d:%d" % (value >> kern_minorbits, value & ((1 << kern_minorbits) - 1))
|
return "%d:%d" % (value >> kern_minorbits,
|
||||||
|
value & ((1 << kern_minorbits) - 1))
|
||||||
|
|
||||||
|
|
||||||
def encode_dev(field, value):
|
def encode_dev(field, value):
|
||||||
dev = [int(x) for x in value.split(':')]
|
dev = [int(x) for x in value.split(':')]
|
||||||
@ -194,19 +223,27 @@ def encode_dev(field, value):
|
|||||||
else:
|
else:
|
||||||
return dev[0] << kern_minorbits | dev[1]
|
return dev[0] << kern_minorbits | dev[1]
|
||||||
|
|
||||||
|
|
||||||
def encode_base64(value):
|
def encode_base64(value):
|
||||||
return base64.encodebytes(value)
|
return base64.encodebytes(value)
|
||||||
|
|
||||||
|
|
||||||
def decode_base64(value):
|
def decode_base64(value):
|
||||||
return base64.decodebytes(value)
|
return base64.decodebytes(value)
|
||||||
|
|
||||||
|
|
||||||
def encode_unix(value):
|
def encode_unix(value):
|
||||||
return quopri.encodestring(value)
|
return quopri.encodestring(value)
|
||||||
|
|
||||||
|
|
||||||
def decode_unix(value):
|
def decode_unix(value):
|
||||||
return quopri.decodestring(value)
|
return quopri.decodestring(value)
|
||||||
|
|
||||||
|
|
||||||
encode = {'unix_name': encode_unix}
|
encode = {'unix_name': encode_unix}
|
||||||
decode = {'unix_name': decode_unix}
|
decode = {'unix_name': decode_unix}
|
||||||
|
|
||||||
|
|
||||||
def get_bytes_enc(field):
|
def get_bytes_enc(field):
|
||||||
c = _custom_conv(field)
|
c = _custom_conv(field)
|
||||||
if c:
|
if c:
|
||||||
@ -214,6 +251,7 @@ def get_bytes_enc(field):
|
|||||||
else:
|
else:
|
||||||
return encode_base64
|
return encode_base64
|
||||||
|
|
||||||
|
|
||||||
def get_bytes_dec(field):
|
def get_bytes_dec(field):
|
||||||
c = _custom_conv(field)
|
c = _custom_conv(field)
|
||||||
if c:
|
if c:
|
||||||
@ -221,6 +259,7 @@ def get_bytes_dec(field):
|
|||||||
else:
|
else:
|
||||||
return decode_base64
|
return decode_base64
|
||||||
|
|
||||||
|
|
||||||
def is_string(value):
|
def is_string(value):
|
||||||
# Python 3 compatibility
|
# Python 3 compatibility
|
||||||
if "basestring" in __builtins__:
|
if "basestring" in __builtins__:
|
||||||
@ -229,6 +268,7 @@ def is_string(value):
|
|||||||
string_types = (str, bytes)
|
string_types = (str, bytes)
|
||||||
return isinstance(value, string_types)
|
return isinstance(value, string_types)
|
||||||
|
|
||||||
|
|
||||||
def _pb2dict_cast(field, value, pretty=False, is_hex=False):
|
def _pb2dict_cast(field, value, pretty=False, is_hex=False):
|
||||||
if not is_hex:
|
if not is_hex:
|
||||||
is_hex = _marked_as_hex(field)
|
is_hex = _marked_as_hex(field)
|
||||||
@ -254,7 +294,7 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
|
|||||||
if flags:
|
if flags:
|
||||||
try:
|
try:
|
||||||
flags_map = flags_maps[flags]
|
flags_map = flags_maps[flags]
|
||||||
except:
|
except Exception:
|
||||||
return "0x%x" % value # flags are better seen as hex anyway
|
return "0x%x" % value # flags are better seen as hex anyway
|
||||||
else:
|
else:
|
||||||
return map_flags(value, flags_map)
|
return map_flags(value, flags_map)
|
||||||
@ -265,7 +305,9 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
|
|||||||
|
|
||||||
return cast(value)
|
return cast(value)
|
||||||
else:
|
else:
|
||||||
raise Exception("Field(%s) has unsupported type %d" % (field.name, field.type))
|
raise Exception("Field(%s) has unsupported type %d" %
|
||||||
|
(field.name, field.type))
|
||||||
|
|
||||||
|
|
||||||
def pb2dict(pb, pretty=False, is_hex=False):
|
def pb2dict(pb, pretty=False, is_hex=False):
|
||||||
"""
|
"""
|
||||||
@ -297,6 +339,7 @@ def pb2dict(pb, pretty = False, is_hex = False):
|
|||||||
d[field.name] = d_val
|
d[field.name] = d_val
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
def _dict2pb_cast(field, value):
|
def _dict2pb_cast(field, value):
|
||||||
# Not considering TYPE_MESSAGE here, as repeated
|
# Not considering TYPE_MESSAGE here, as repeated
|
||||||
# and non-repeated messages need special treatment
|
# and non-repeated messages need special treatment
|
||||||
@ -315,7 +358,7 @@ def _dict2pb_cast(field, value):
|
|||||||
if flags:
|
if flags:
|
||||||
try:
|
try:
|
||||||
flags_map = flags_maps[flags]
|
flags_map = flags_maps[flags]
|
||||||
except:
|
except Exception:
|
||||||
pass # Try to use plain string cast
|
pass # Try to use plain string cast
|
||||||
else:
|
else:
|
||||||
return unmap_flags(value, flags_map)
|
return unmap_flags(value, flags_map)
|
||||||
@ -323,7 +366,7 @@ def _dict2pb_cast(field, value):
|
|||||||
dct = _marked_as_dict(field)
|
dct = _marked_as_dict(field)
|
||||||
if dct:
|
if dct:
|
||||||
ret = dict_maps[dct][1][field.name].get(value, None)
|
ret = dict_maps[dct][1][field.name].get(value, None)
|
||||||
if ret == None:
|
if ret is None:
|
||||||
ret = cast(value, 0)
|
ret = cast(value, 0)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -333,7 +376,9 @@ def _dict2pb_cast(field, value):
|
|||||||
else:
|
else:
|
||||||
return cast(value)
|
return cast(value)
|
||||||
else:
|
else:
|
||||||
raise Exception("Field(%s) has unsupported type %d" % (field.name, field.type))
|
raise Exception("Field(%s) has unsupported type %d" %
|
||||||
|
(field.name, field.type))
|
||||||
|
|
||||||
|
|
||||||
def dict2pb(d, pb):
|
def dict2pb(d, pb):
|
||||||
"""
|
"""
|
||||||
@ -357,7 +402,8 @@ def dict2pb(d, pb):
|
|||||||
pb_val.append(socket.htonl((ival >> (32 * 1)) & 0xFFFFFFFF))
|
pb_val.append(socket.htonl((ival >> (32 * 1)) & 0xFFFFFFFF))
|
||||||
pb_val.append(socket.htonl((ival >> (32 * 0)) & 0xFFFFFFFF))
|
pb_val.append(socket.htonl((ival >> (32 * 0)) & 0xFFFFFFFF))
|
||||||
else:
|
else:
|
||||||
raise Exception("Unknown IP address version %d" % val.version)
|
raise Exception("Unknown IP address version %d" %
|
||||||
|
val.version)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for v in value:
|
for v in value:
|
||||||
|
@ -8,5 +8,4 @@ setup(name = "crit",
|
|||||||
url="https://github.com/checkpoint-restore/criu",
|
url="https://github.com/checkpoint-restore/criu",
|
||||||
package_dir={'pycriu': 'lib/py'},
|
package_dir={'pycriu': 'lib/py'},
|
||||||
packages=["pycriu", "pycriu.images"],
|
packages=["pycriu", "pycriu.images"],
|
||||||
scripts = ["crit/crit"]
|
scripts=["crit/crit"])
|
||||||
)
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/bin/env python2
|
#!/bin/env python2
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
# This program parses criu magic.h file and produces
|
# This program parses criu magic.h file and produces
|
||||||
# magic.py with all *_MAGIC constants except RAW and V1.
|
# magic.py with all *_MAGIC constants except RAW and V1.
|
||||||
def main(argv):
|
def main(argv):
|
||||||
@ -57,5 +58,6 @@ def main(argv):
|
|||||||
f.close()
|
f.close()
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(sys.argv)
|
main(sys.argv)
|
||||||
|
@ -13,15 +13,15 @@ sport = os.getenv("TCP_SPORT", "12345")
|
|||||||
dport = os.getenv("TCP_DPORT", "54321")
|
dport = os.getenv("TCP_DPORT", "54321")
|
||||||
|
|
||||||
print(sys.argv[1])
|
print(sys.argv[1])
|
||||||
args = [sys.argv[1],
|
args = [
|
||||||
"--addr", src, "--port", sport, "--seq", "555",
|
sys.argv[1], "--addr", src, "--port", sport, "--seq", "555", "--next",
|
||||||
"--next",
|
"--addr", dst, "--port", dport, "--seq", "666", "--reverse", "--",
|
||||||
"--addr", dst, "--port", dport, "--seq", "666",
|
"./tcp-test.py"
|
||||||
"--reverse", "--", "./tcp-test.py"]
|
]
|
||||||
|
|
||||||
p1 = Popen(args + ["dst"], stdout=PIPE, stdin=PIPE)
|
p1 = Popen(args + ["dst"], stdout=PIPE, stdin=PIPE)
|
||||||
|
|
||||||
args.remove("--reverse");
|
args.remove("--reverse")
|
||||||
|
|
||||||
p2 = Popen(args + ["src"], stdout=PIPE, stdin=PIPE)
|
p2 = Popen(args + ["src"], stdout=PIPE, stdin=PIPE)
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ str2 = m.hexdigest()
|
|||||||
|
|
||||||
if str2 != eval(s):
|
if str2 != eval(s):
|
||||||
print("FAIL", repr(str2), repr(s))
|
print("FAIL", repr(str2), repr(s))
|
||||||
sys.exit(5);
|
sys.exit(5)
|
||||||
|
|
||||||
s = p1.stdout.read()
|
s = p1.stdout.read()
|
||||||
m = hashlib.md5()
|
m = hashlib.md5()
|
||||||
@ -52,7 +52,7 @@ str1 = m.hexdigest()
|
|||||||
s = p2.stdout.read()
|
s = p2.stdout.read()
|
||||||
if str1 != eval(s):
|
if str1 != eval(s):
|
||||||
print("FAIL", repr(str1), s)
|
print("FAIL", repr(str1), s)
|
||||||
sys.exit(5);
|
sys.exit(5)
|
||||||
|
|
||||||
if p1.wait():
|
if p1.wait():
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -25,7 +25,8 @@ for act in open(af):
|
|||||||
if act[2] == 'EMPTY':
|
if act[2] == 'EMPTY':
|
||||||
errors.append('Action %s misses CRTOOLS_INIT_PID' % act[0])
|
errors.append('Action %s misses CRTOOLS_INIT_PID' % act[0])
|
||||||
elif not act[2].isdigit() or int(act[2]) == 0:
|
elif not act[2].isdigit() or int(act[2]) == 0:
|
||||||
errors.append('Action %s PID is not number (%s)' % (act[0], act[2]))
|
errors.append('Action %s PID is not number (%s)' %
|
||||||
|
(act[0], act[2]))
|
||||||
|
|
||||||
actions -= set([act[0]])
|
actions -= set([act[0]])
|
||||||
|
|
||||||
|
@ -6,11 +6,13 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
find = subprocess.Popen(['find', 'test/dump/', '-size', '+0', '-name', '*.img'],
|
find = subprocess.Popen(
|
||||||
|
['find', 'test/dump/', '-size', '+0', '-name', '*.img'],
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE)
|
||||||
|
|
||||||
test_pass = True
|
test_pass = True
|
||||||
|
|
||||||
|
|
||||||
def recode_and_check(imgf, o_img, pretty):
|
def recode_and_check(imgf, o_img, pretty):
|
||||||
try:
|
try:
|
||||||
pb = pycriu.images.loads(o_img, pretty)
|
pb = pycriu.images.loads(o_img, pretty)
|
||||||
|
@ -10,6 +10,7 @@ import subprocess
|
|||||||
|
|
||||||
criu_bin = '../../criu/criu'
|
criu_bin = '../../criu/criu'
|
||||||
|
|
||||||
|
|
||||||
def mix(nr_tasks, nr_pipes):
|
def mix(nr_tasks, nr_pipes):
|
||||||
# Returned is the list of combinations.
|
# Returned is the list of combinations.
|
||||||
# Each combination is the lists of pipe descriptors.
|
# Each combination is the lists of pipe descriptors.
|
||||||
@ -114,6 +115,7 @@ def check_pipe(kids, fds, comb, inos):
|
|||||||
return res + 'end(%d)' % e
|
return res + 'end(%d)' % e
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def check_pipes(kids, pipes, comb):
|
def check_pipes(kids, pipes, comb):
|
||||||
# Kids contain pids
|
# Kids contain pids
|
||||||
# Pipes contain pipe FDs
|
# Pipes contain pipe FDs
|
||||||
@ -198,14 +200,20 @@ def cr_test(pid):
|
|||||||
img_dir = 'pimg_%d' % pid
|
img_dir = 'pimg_%d' % pid
|
||||||
try:
|
try:
|
||||||
os.mkdir(img_dir)
|
os.mkdir(img_dir)
|
||||||
subprocess.check_call([criu_bin, 'dump', '-t', '%d' % pid, '-D', img_dir, '-o', 'dump.log', '-v4', '-j'])
|
subprocess.check_call([
|
||||||
|
criu_bin, 'dump', '-t',
|
||||||
|
'%d' % pid, '-D', img_dir, '-o', 'dump.log', '-v4', '-j'
|
||||||
|
])
|
||||||
except:
|
except:
|
||||||
print('`- dump fail')
|
print('`- dump fail')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.waitpid(pid, 0)
|
os.waitpid(pid, 0)
|
||||||
subprocess.check_call([criu_bin, 'restore', '-D', img_dir, '-o', 'rst.log', '-v4', '-j', '-d', '-S'])
|
subprocess.check_call([
|
||||||
|
criu_bin, 'restore', '-D', img_dir, '-o', 'rst.log', '-v4', '-j',
|
||||||
|
'-d', '-S'
|
||||||
|
])
|
||||||
except:
|
except:
|
||||||
print('`- restore fail')
|
print('`- restore fail')
|
||||||
return False
|
return False
|
||||||
|
@ -25,12 +25,14 @@ sk_type_s = {
|
|||||||
# - do() method, that actually does what's required
|
# - do() method, that actually does what's required
|
||||||
# - show() method to return the string description of what's done
|
# - show() method to return the string description of what's done
|
||||||
|
|
||||||
|
|
||||||
def mk_socket(st, typ):
|
def mk_socket(st, typ):
|
||||||
st.sk_id += 1
|
st.sk_id += 1
|
||||||
sk = sock(st.sk_id, typ)
|
sk = sock(st.sk_id, typ)
|
||||||
st.add_socket(sk)
|
st.add_socket(sk)
|
||||||
return sk
|
return sk
|
||||||
|
|
||||||
|
|
||||||
class act_socket:
|
class act_socket:
|
||||||
def __init__(self, typ):
|
def __init__(self, typ):
|
||||||
self.typ = typ
|
self.typ = typ
|
||||||
@ -174,12 +176,14 @@ class act_sendmsg:
|
|||||||
sk.sendto(msgv, sock.real_name_for(self.to_id))
|
sk.sendto(msgv, sock.real_name_for(self.to_id))
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
return 'send(%d, %d, $message-%d)' % (self.sk_id, self.to_id, self.msg_id)
|
return 'send(%d, %d, $message-%d)' % (self.sk_id, self.to_id,
|
||||||
|
self.msg_id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def msgval(msgid, pref=''):
|
def msgval(msgid, pref=''):
|
||||||
return '%sMSG%d' % (pref, msgid)
|
return '%sMSG%d' % (pref, msgid)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Description of a socket
|
# Description of a socket
|
||||||
#
|
#
|
||||||
@ -425,6 +429,7 @@ def set_nonblock(sk):
|
|||||||
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
|
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
|
||||||
|
|
||||||
|
|
||||||
CHK_FAIL_UNKNOWN = 10
|
CHK_FAIL_UNKNOWN = 10
|
||||||
CHK_FAIL_SOCKET = 11
|
CHK_FAIL_SOCKET = 11
|
||||||
CHK_FAIL_STAT = 12
|
CHK_FAIL_STAT = 12
|
||||||
@ -455,6 +460,7 @@ fail_desc = {
|
|||||||
CHK_FAIL_RESTORE: 'Cannot restore',
|
CHK_FAIL_RESTORE: 'Cannot restore',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def chk_real_state(st):
|
def chk_real_state(st):
|
||||||
# Before enything else -- check that we still have
|
# Before enything else -- check that we still have
|
||||||
# all the sockets at hands
|
# all the sockets at hands
|
||||||
@ -485,16 +491,16 @@ def chk_real_state(st):
|
|||||||
rsk = st.real_sockets[sk.sk_id]
|
rsk = st.real_sockets[sk.sk_id]
|
||||||
r_listen = rsk.getsockopt(socket.SOL_SOCKET, socket.SO_ACCEPTCONN)
|
r_listen = rsk.getsockopt(socket.SOL_SOCKET, socket.SO_ACCEPTCONN)
|
||||||
if (sk.listen and r_listen == 0) or (not sk.listen and r_listen == 1):
|
if (sk.listen and r_listen == 0) or (not sk.listen and r_listen == 1):
|
||||||
print("FAIL: Socket %d listen %d, expected %d"
|
print("FAIL: Socket %d listen %d, expected %d" %
|
||||||
% (sk.sk_id, r_listen, sk.listen and 1 or 0))
|
(sk.sk_id, r_listen, sk.listen and 1 or 0))
|
||||||
return CHK_FAIL_LISTEN
|
return CHK_FAIL_LISTEN
|
||||||
|
|
||||||
if sk.name:
|
if sk.name:
|
||||||
r_name = rsk.getsockname()
|
r_name = rsk.getsockname()
|
||||||
w_name = sock.real_name_for(sk.name)
|
w_name = sock.real_name_for(sk.name)
|
||||||
if r_name != w_name:
|
if r_name != w_name:
|
||||||
print('FAIL: Socket %d name mismatch [%s], want [%s]'
|
print('FAIL: Socket %d name mismatch [%s], want [%s]' %
|
||||||
% (sk.sk_id, r_name, w_name))
|
(sk.sk_id, r_name, w_name))
|
||||||
return CHK_FAIL_NAME
|
return CHK_FAIL_NAME
|
||||||
|
|
||||||
# Second -- check (accept) pending connections
|
# Second -- check (accept) pending connections
|
||||||
@ -513,7 +519,8 @@ def chk_real_state(st):
|
|||||||
try:
|
try:
|
||||||
acc.do(st)
|
acc.do(st)
|
||||||
except:
|
except:
|
||||||
print('FAIL: Cannot accept pending connection for %d' % sk.sk_id)
|
print('FAIL: Cannot accept pending connection for %d' %
|
||||||
|
sk.sk_id)
|
||||||
return CHK_FAIL_ACCEPT
|
return CHK_FAIL_ACCEPT
|
||||||
|
|
||||||
print(' `- did %s' % acc.show())
|
print(' `- did %s' % acc.show())
|
||||||
@ -536,13 +543,13 @@ def chk_real_state(st):
|
|||||||
|
|
||||||
w_msg = act_sendmsg.msgval(msg[1])
|
w_msg = act_sendmsg.msgval(msg[1])
|
||||||
if r_msg != w_msg:
|
if r_msg != w_msg:
|
||||||
print('FAIL: Message misorder: %s want %s (from %d)'
|
print('FAIL: Message misorder: %s want %s (from %d)' %
|
||||||
%(r_msg, w_msg, msg[0]))
|
(r_msg, w_msg, msg[0]))
|
||||||
return CHK_FAIL_RECV_MIX
|
return CHK_FAIL_RECV_MIX
|
||||||
|
|
||||||
# TODO -- check sender
|
# TODO -- check sender
|
||||||
print(' `- recvd %d.%d msg %s -> %d'
|
print(' `- recvd %d.%d msg %s -> %d' %
|
||||||
% (msg[0], msg[1], m_from, sk.sk_id))
|
(msg[0], msg[1], m_from, sk.sk_id))
|
||||||
|
|
||||||
# Finally, after all sockets are visible and all inqueues are
|
# Finally, after all sockets are visible and all inqueues are
|
||||||
# drained -- check the sockets connectivity
|
# drained -- check the sockets connectivity
|
||||||
@ -557,7 +564,8 @@ def chk_real_state(st):
|
|||||||
rsk = st.real_sockets[sk.sk_id]
|
rsk = st.real_sockets[sk.sk_id]
|
||||||
psk = st.real_sockets[sk.peer]
|
psk = st.real_sockets[sk.peer]
|
||||||
set_nonblock(psk)
|
set_nonblock(psk)
|
||||||
msgv = act_sendmsg.msgval(3 * sk.sk_id + 5 * sk.peer, 'C') # just random
|
msgv = act_sendmsg.msgval(3 * sk.sk_id + 5 * sk.peer,
|
||||||
|
'C') # just random
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rsk.send(msgv)
|
rsk.send(msgv)
|
||||||
@ -572,8 +580,8 @@ def chk_real_state(st):
|
|||||||
# the hard way -- also check for the message being
|
# the hard way -- also check for the message being
|
||||||
# delivered for real
|
# delivered for real
|
||||||
if rmsg != msgv:
|
if rmsg != msgv:
|
||||||
print('FAIL: Connectivity %d -> %d not verified'
|
print('FAIL: Connectivity %d -> %d not verified' %
|
||||||
% (sk.sk_id, sk.peer))
|
(sk.sk_id, sk.peer))
|
||||||
return CHK_FAIL_CONNECT2
|
return CHK_FAIL_CONNECT2
|
||||||
|
|
||||||
print(' `- checked %d -> %d with %s' % (sk.sk_id, sk.peer, msgv))
|
print(' `- checked %d -> %d with %s' % (sk.sk_id, sk.peer, msgv))
|
||||||
@ -609,7 +617,10 @@ def chk_state(st, opts):
|
|||||||
img_path = "sti_" + st.describe()
|
img_path = "sti_" + st.describe()
|
||||||
try:
|
try:
|
||||||
os.mkdir(img_path)
|
os.mkdir(img_path)
|
||||||
subprocess.check_call([criu_bin, "dump", "-t", "%d" % pid, "-D", img_path, "-v4", "-o", "dump.log", "-j"])
|
subprocess.check_call([
|
||||||
|
criu_bin, "dump", "-t",
|
||||||
|
"%d" % pid, "-D", img_path, "-v4", "-o", "dump.log", "-j"
|
||||||
|
])
|
||||||
except:
|
except:
|
||||||
print("Dump failed")
|
print("Dump failed")
|
||||||
os.kill(pid, signal.SIGKILL)
|
os.kill(pid, signal.SIGKILL)
|
||||||
@ -618,7 +629,10 @@ def chk_state(st, opts):
|
|||||||
print("`- restore")
|
print("`- restore")
|
||||||
try:
|
try:
|
||||||
os.waitpid(pid, 0)
|
os.waitpid(pid, 0)
|
||||||
subprocess.check_call([criu_bin, "restore", "-D", img_path, "-v4", "-o", "rst.log", "-j", "-d", "-S"])
|
subprocess.check_call([
|
||||||
|
criu_bin, "restore", "-D", img_path, "-v4", "-o", "rst.log", "-j",
|
||||||
|
"-d", "-S"
|
||||||
|
])
|
||||||
except:
|
except:
|
||||||
print("Restore failed")
|
print("Restore failed")
|
||||||
return CHK_FAIL_RESTORE
|
return CHK_FAIL_RESTORE
|
||||||
@ -722,8 +736,12 @@ p.add_argument("--depth", help = "Depth of generated tree", default = '8')
|
|||||||
p.add_argument("--sockets", help="Maximum number of sockets", default='1')
|
p.add_argument("--sockets", help="Maximum number of sockets", default='1')
|
||||||
p.add_argument("--dgram", help="Use SOCK_DGRAM sockets", action='store_true')
|
p.add_argument("--dgram", help="Use SOCK_DGRAM sockets", action='store_true')
|
||||||
p.add_argument("--stream", help="Use SOCK_STREAM sockets", action='store_true')
|
p.add_argument("--stream", help="Use SOCK_STREAM sockets", action='store_true')
|
||||||
p.add_argument("--gen", help = "Only generate and show states", action = 'store_true')
|
p.add_argument("--gen",
|
||||||
p.add_argument("--run", help = "Run the states, but don't C/R", action = 'store_true')
|
help="Only generate and show states",
|
||||||
|
action='store_true')
|
||||||
|
p.add_argument("--run",
|
||||||
|
help="Run the states, but don't C/R",
|
||||||
|
action='store_true')
|
||||||
p.add_argument("--keep", help="Don't stop on error", action='store_true')
|
p.add_argument("--keep", help="Don't stop on error", action='store_true')
|
||||||
opts = p.parse_args()
|
opts = p.parse_args()
|
||||||
opts.depth = int(opts.depth)
|
opts.depth = int(opts.depth)
|
||||||
@ -751,4 +769,5 @@ if len(failed) == 0:
|
|||||||
else:
|
else:
|
||||||
print('FAIL %d/%d' % (len(failed), len(seen)))
|
print('FAIL %d/%d' % (len(failed), len(seen)))
|
||||||
for f in failed:
|
for f in failed:
|
||||||
print("\t%-50s: %s" % (f[0], fail_desc.get(f[1], 'unknown reason %d' % f[1])))
|
print("\t%-50s: %s" %
|
||||||
|
(f[0], fail_desc.get(f[1], 'unknown reason %d' % f[1])))
|
||||||
|
@ -4,7 +4,6 @@ import os
|
|||||||
import pty
|
import pty
|
||||||
import termios
|
import termios
|
||||||
|
|
||||||
|
|
||||||
ctl = False
|
ctl = False
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,13 +5,19 @@ import os, sys, time, signal, pty
|
|||||||
master, slave = pty.openpty()
|
master, slave = pty.openpty()
|
||||||
|
|
||||||
p = subprocess.Popen(["setsid", "--ctty", "sleep", "10000"],
|
p = subprocess.Popen(["setsid", "--ctty", "sleep", "10000"],
|
||||||
stdin = slave, stdout = slave, stderr = slave, close_fds = True)
|
stdin=slave,
|
||||||
|
stdout=slave,
|
||||||
|
stderr=slave,
|
||||||
|
close_fds=True)
|
||||||
st = os.stat("/proc/self/fd/%d" % slave)
|
st = os.stat("/proc/self/fd/%d" % slave)
|
||||||
ttyid = "tty[%x:%x]" % (st.st_rdev, st.st_dev)
|
ttyid = "tty[%x:%x]" % (st.st_rdev, st.st_dev)
|
||||||
os.close(slave)
|
os.close(slave)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
ret = subprocess.Popen(["../../../criu/criu", "dump", "-t", str(p.pid), "-v4", "--external", ttyid]).wait()
|
ret = subprocess.Popen([
|
||||||
|
"../../../criu/criu", "dump", "-t",
|
||||||
|
str(p.pid), "-v4", "--external", ttyid
|
||||||
|
]).wait()
|
||||||
if ret:
|
if ret:
|
||||||
sys.exit(ret)
|
sys.exit(ret)
|
||||||
p.wait()
|
p.wait()
|
||||||
@ -21,7 +27,10 @@ os.close(master)
|
|||||||
|
|
||||||
ttyid = "fd[%d]:tty[%x:%x]" % (slave, st.st_rdev, st.st_dev)
|
ttyid = "fd[%d]:tty[%x:%x]" % (slave, st.st_rdev, st.st_dev)
|
||||||
|
|
||||||
ret = subprocess.Popen(["../../../criu/criu", "restore", "-v4", "--inherit-fd", ttyid, "--restore-sibling", "--restore-detach"]).wait()
|
ret = subprocess.Popen([
|
||||||
|
"../../../criu/criu", "restore", "-v4", "--inherit-fd", ttyid,
|
||||||
|
"--restore-sibling", "--restore-detach"
|
||||||
|
]).wait()
|
||||||
if ret:
|
if ret:
|
||||||
sys.exit(ret)
|
sys.exit(ret)
|
||||||
os.close(slave)
|
os.close(slave)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import tempfile, random
|
import tempfile, random
|
||||||
|
|
||||||
|
|
||||||
def mount(src, dst, shared, private, slave):
|
def mount(src, dst, shared, private, slave):
|
||||||
cmd = "mount"
|
cmd = "mount"
|
||||||
if shared:
|
if shared:
|
||||||
@ -19,6 +20,7 @@ def mount(src, dst, shared, private, slave):
|
|||||||
if ret:
|
if ret:
|
||||||
print("failed")
|
print("failed")
|
||||||
|
|
||||||
|
|
||||||
root = tempfile.mkdtemp(prefix="root.mount", dir="/tmp")
|
root = tempfile.mkdtemp(prefix="root.mount", dir="/tmp")
|
||||||
mount(None, root, 1, 0, 0)
|
mount(None, root, 1, 0, 0)
|
||||||
mounts = [root]
|
mounts = [root]
|
||||||
@ -27,5 +29,8 @@ for i in range(10):
|
|||||||
dstdir = random.choice(mounts)
|
dstdir = random.choice(mounts)
|
||||||
dst = tempfile.mkdtemp(prefix="mount", dir=dstdir)
|
dst = tempfile.mkdtemp(prefix="mount", dir=dstdir)
|
||||||
src = random.choice(mounts + [None])
|
src = random.choice(mounts + [None])
|
||||||
mount(src, dst, random.randint(0,100) > 50, random.randint(0,100) > 90, random.randint(0,100) > 50)
|
mount(src, dst,
|
||||||
|
random.randint(0, 100) > 50,
|
||||||
|
random.randint(0, 100) > 90,
|
||||||
|
random.randint(0, 100) > 50)
|
||||||
mounts.append(dst)
|
mounts.append(dst)
|
||||||
|
@ -99,7 +99,9 @@ def test_broken_configuration_file():
|
|||||||
def search_in_log_file(log, message):
|
def search_in_log_file(log, message):
|
||||||
with open(os.path.join(args['dir'], log)) as f:
|
with open(os.path.join(args['dir'], log)) as f:
|
||||||
if message not in f.read():
|
if message not in f.read():
|
||||||
print('FAIL: Missing the expected error message (%s) in the log file' % message)
|
print(
|
||||||
|
'FAIL: Missing the expected error message (%s) in the log file'
|
||||||
|
% message)
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
|
||||||
@ -175,8 +177,11 @@ def test_rpc_with_configuration_file_overwriting_rpc():
|
|||||||
check_results(resp, log)
|
check_results(resp, log)
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Test config files using CRIU RPC")
|
parser = argparse.ArgumentParser(
|
||||||
parser.add_argument('dir', type = str, help = "Directory where CRIU images should be placed")
|
description="Test config files using CRIU RPC")
|
||||||
|
parser.add_argument('dir',
|
||||||
|
type=str,
|
||||||
|
help="Directory where CRIU images should be placed")
|
||||||
|
|
||||||
args = vars(parser.parse_args())
|
args = vars(parser.parse_args())
|
||||||
|
|
||||||
|
@ -7,10 +7,13 @@ import argparse
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Test errno reported by CRIU RPC")
|
parser = argparse.ArgumentParser(description="Test errno reported by CRIU RPC")
|
||||||
parser.add_argument('socket', type=str, help="CRIU service socket")
|
parser.add_argument('socket', type=str, help="CRIU service socket")
|
||||||
parser.add_argument('dir', type = str, help = "Directory where CRIU images should be placed")
|
parser.add_argument('dir',
|
||||||
|
type=str,
|
||||||
|
help="Directory where CRIU images should be placed")
|
||||||
|
|
||||||
args = vars(parser.parse_args())
|
args = vars(parser.parse_args())
|
||||||
|
|
||||||
|
|
||||||
# Prepare dir for images
|
# Prepare dir for images
|
||||||
class test:
|
class test:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -73,7 +76,9 @@ class test:
|
|||||||
print('Success')
|
print('Success')
|
||||||
|
|
||||||
def process_exists(self):
|
def process_exists(self):
|
||||||
print('Try to restore process which pid is already taken by other process')
|
print(
|
||||||
|
'Try to restore process which pid is already taken by other process'
|
||||||
|
)
|
||||||
|
|
||||||
# Perform self-dump
|
# Perform self-dump
|
||||||
req = self.get_base_req()
|
req = self.get_base_req()
|
||||||
@ -131,5 +136,6 @@ class test:
|
|||||||
self.bad_options()
|
self.bad_options()
|
||||||
self.bad_request()
|
self.bad_request()
|
||||||
|
|
||||||
|
|
||||||
t = test()
|
t = test()
|
||||||
t.run()
|
t.run()
|
||||||
|
@ -6,7 +6,9 @@ import argparse
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Test page-server using CRIU RPC")
|
parser = argparse.ArgumentParser(description="Test page-server using CRIU RPC")
|
||||||
parser.add_argument('socket', type=str, help="CRIU service socket")
|
parser.add_argument('socket', type=str, help="CRIU service socket")
|
||||||
parser.add_argument('dir', type = str, help = "Directory where CRIU images should be placed")
|
parser.add_argument('dir',
|
||||||
|
type=str,
|
||||||
|
help="Directory where CRIU images should be placed")
|
||||||
|
|
||||||
args = vars(parser.parse_args())
|
args = vars(parser.parse_args())
|
||||||
|
|
||||||
@ -42,12 +44,12 @@ else:
|
|||||||
else:
|
else:
|
||||||
print('Can\'t check that process %d exists' % (resp.ps.pid))
|
print('Can\'t check that process %d exists' % (resp.ps.pid))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
print('Success, page-server pid %d started on port %u' %(resp.ps.pid, resp.ps.port))
|
print('Success, page-server pid %d started on port %u' %
|
||||||
|
(resp.ps.pid, resp.ps.port))
|
||||||
else:
|
else:
|
||||||
print('Failed to start page-server')
|
print('Failed to start page-server')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
# Perform self-dump
|
# Perform self-dump
|
||||||
print('Dumping myself using page-server')
|
print('Dumping myself using page-server')
|
||||||
req.type = rpc.DUMP
|
req.type = rpc.DUMP
|
||||||
|
@ -4,9 +4,12 @@ import socket, os, sys
|
|||||||
import rpc_pb2 as rpc
|
import rpc_pb2 as rpc
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Test ability to restore a process from images using CRIU RPC")
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Test ability to restore a process from images using CRIU RPC")
|
||||||
parser.add_argument('socket', type=str, help="CRIU service socket")
|
parser.add_argument('socket', type=str, help="CRIU service socket")
|
||||||
parser.add_argument('dir', type = str, help = "Directory where CRIU images could be found")
|
parser.add_argument('dir',
|
||||||
|
type=str,
|
||||||
|
help="Directory where CRIU images could be found")
|
||||||
|
|
||||||
args = vars(parser.parse_args())
|
args = vars(parser.parse_args())
|
||||||
|
|
||||||
|
@ -4,9 +4,12 @@ import socket, os, sys
|
|||||||
import rpc_pb2 as rpc
|
import rpc_pb2 as rpc
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Test dump/restore using CRIU RPC")
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Test dump/restore using CRIU RPC")
|
||||||
parser.add_argument('socket', type=str, help="CRIU service socket")
|
parser.add_argument('socket', type=str, help="CRIU service socket")
|
||||||
parser.add_argument('dir', type = str, help = "Directory where CRIU images should be placed")
|
parser.add_argument('dir',
|
||||||
|
type=str,
|
||||||
|
help="Directory where CRIU images should be placed")
|
||||||
|
|
||||||
args = vars(parser.parse_args())
|
args = vars(parser.parse_args())
|
||||||
|
|
||||||
|
@ -6,10 +6,12 @@ cr_bin = "../../../criu/criu"
|
|||||||
|
|
||||||
os.chdir(os.getcwd())
|
os.chdir(os.getcwd())
|
||||||
|
|
||||||
|
|
||||||
def create_pty():
|
def create_pty():
|
||||||
(fd1, fd2) = pty.openpty()
|
(fd1, fd2) = pty.openpty()
|
||||||
return (os.fdopen(fd1, "w+"), os.fdopen(fd2, "w+"))
|
return (os.fdopen(fd1, "w+"), os.fdopen(fd2, "w+"))
|
||||||
|
|
||||||
|
|
||||||
if not os.access("work", os.X_OK):
|
if not os.access("work", os.X_OK):
|
||||||
os.mkdir("work", 0755)
|
os.mkdir("work", 0755)
|
||||||
|
|
||||||
@ -53,7 +55,8 @@ if cpid == 0:
|
|||||||
fcntl.ioctl(m.fileno(), termios.TIOCSCTTY, 1)
|
fcntl.ioctl(m.fileno(), termios.TIOCSCTTY, 1)
|
||||||
cmd = [cr_bin, "restore", "-j", "-D", "work", "-v"]
|
cmd = [cr_bin, "restore", "-j", "-D", "work", "-v"]
|
||||||
print("Run: %s" % " ".join(cmd))
|
print("Run: %s" % " ".join(cmd))
|
||||||
ret = subprocess.Popen([cr_bin, "restore", "-j", "-D", "work", "-v"]).wait()
|
ret = subprocess.Popen([cr_bin, "restore", "-j", "-D", "work",
|
||||||
|
"-v"]).wait()
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
471
test/zdtm.py
471
test/zdtm.py
@ -122,7 +122,8 @@ def check_core_files():
|
|||||||
if not reports:
|
if not reports:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
while subprocess.Popen(r"ps axf | grep 'abrt\.sh'", shell = True).wait() == 0:
|
while subprocess.Popen(r"ps axf | grep 'abrt\.sh'",
|
||||||
|
shell=True).wait() == 0:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
for i in reports:
|
for i in reports:
|
||||||
@ -164,7 +165,10 @@ class host_flavor:
|
|||||||
|
|
||||||
|
|
||||||
class ns_flavor:
|
class ns_flavor:
|
||||||
__root_dirs = ["/bin", "/sbin", "/etc", "/lib", "/lib64", "/dev", "/dev/pts", "/dev/net", "/tmp", "/usr", "/proc", "/run"]
|
__root_dirs = [
|
||||||
|
"/bin", "/sbin", "/etc", "/lib", "/lib64", "/dev", "/dev/pts",
|
||||||
|
"/dev/net", "/tmp", "/usr", "/proc", "/run"
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, opts):
|
def __init__(self, opts):
|
||||||
self.name = "ns"
|
self.name = "ns"
|
||||||
@ -183,27 +187,36 @@ class ns_flavor:
|
|||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno != errno.EEXIST:
|
if e.errno != errno.EEXIST:
|
||||||
raise
|
raise
|
||||||
dst = tempfile.mktemp(".tso", "", self.root + os.path.dirname(fname))
|
dst = tempfile.mktemp(".tso", "",
|
||||||
|
self.root + os.path.dirname(fname))
|
||||||
shutil.copy2(fname, dst)
|
shutil.copy2(fname, dst)
|
||||||
os.rename(dst, tfname)
|
os.rename(dst, tfname)
|
||||||
|
|
||||||
def __copy_libs(self, binary):
|
def __copy_libs(self, binary):
|
||||||
ldd = subprocess.Popen(["ldd", binary], stdout=subprocess.PIPE)
|
ldd = subprocess.Popen(["ldd", binary], stdout=subprocess.PIPE)
|
||||||
xl = re.compile(r'^(linux-gate.so|linux-vdso(64)?.so|not a dynamic|.*\s*ldd\s)')
|
xl = re.compile(
|
||||||
|
r'^(linux-gate.so|linux-vdso(64)?.so|not a dynamic|.*\s*ldd\s)')
|
||||||
|
|
||||||
# This Mayakovsky-style code gets list of libraries a binary
|
# This Mayakovsky-style code gets list of libraries a binary
|
||||||
# needs minus vdso and gate .so-s
|
# needs minus vdso and gate .so-s
|
||||||
libs = map(lambda x: x[1] == '=>' and x[2] or x[0],
|
libs = map(
|
||||||
map(lambda x: str(x).split(),
|
lambda x: x[1] == '=>' and x[2] or x[0],
|
||||||
filter(lambda x: not xl.match(x),
|
map(
|
||||||
map(lambda x: str(x).strip(),
|
lambda x: str(x).split(),
|
||||||
filter(lambda x: str(x).startswith('\t'), ldd.stdout.read().decode('ascii').splitlines())))))
|
filter(
|
||||||
|
lambda x: not xl.match(x),
|
||||||
|
map(
|
||||||
|
lambda x: str(x).strip(),
|
||||||
|
filter(lambda x: str(x).startswith('\t'),
|
||||||
|
ldd.stdout.read().decode(
|
||||||
|
'ascii').splitlines())))))
|
||||||
|
|
||||||
ldd.wait()
|
ldd.wait()
|
||||||
|
|
||||||
for lib in libs:
|
for lib in libs:
|
||||||
if not os.access(lib, os.F_OK):
|
if not os.access(lib, os.F_OK):
|
||||||
raise test_fail_exc("Can't find lib %s required by %s" % (lib, binary))
|
raise test_fail_exc("Can't find lib %s required by %s" %
|
||||||
|
(lib, binary))
|
||||||
self.__copy_one(lib)
|
self.__copy_one(lib)
|
||||||
|
|
||||||
def __mknod(self, name, rdev=None):
|
def __mknod(self, name, rdev=None):
|
||||||
@ -242,7 +255,8 @@ class ns_flavor:
|
|||||||
raise test_fail_exc("Deps check %s failed" % deps)
|
raise test_fail_exc("Deps check %s failed" % deps)
|
||||||
|
|
||||||
def init(self, l_bins, x_bins):
|
def init(self, l_bins, x_bins):
|
||||||
subprocess.check_call(["mount", "--make-slave", "--bind", ".", self.root])
|
subprocess.check_call(
|
||||||
|
["mount", "--make-slave", "--bind", ".", self.root])
|
||||||
self.root_mounted = True
|
self.root_mounted = True
|
||||||
|
|
||||||
if not os.access(self.root + "/.constructed", os.F_OK):
|
if not os.access(self.root + "/.constructed", os.F_OK):
|
||||||
@ -308,8 +322,7 @@ def decode_flav(i):
|
|||||||
|
|
||||||
|
|
||||||
def tail(path):
|
def tail(path):
|
||||||
p = subprocess.Popen(['tail', '-n1', path],
|
p = subprocess.Popen(['tail', '-n1', path], stdout=subprocess.PIPE)
|
||||||
stdout = subprocess.PIPE)
|
|
||||||
out = p.stdout.readline()
|
out = p.stdout.readline()
|
||||||
p.wait()
|
p.wait()
|
||||||
return out.decode()
|
return out.decode()
|
||||||
@ -342,6 +355,7 @@ def wait_pid_die(pid, who, tmo = 30):
|
|||||||
def test_flag(tdesc, flag):
|
def test_flag(tdesc, flag):
|
||||||
return flag in tdesc.get('flags', '').split()
|
return flag in tdesc.get('flags', '').split()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Exception thrown when something inside the test goes wrong,
|
# Exception thrown when something inside the test goes wrong,
|
||||||
# e.g. test doesn't start, criu returns with non zero code or
|
# e.g. test doesn't start, criu returns with non zero code or
|
||||||
@ -361,6 +375,7 @@ class test_fail_expected_exc(Exception):
|
|||||||
def __init__(self, cr_action):
|
def __init__(self, cr_action):
|
||||||
self.cr_action = cr_action
|
self.cr_action = cr_action
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# A test from zdtm/ directory.
|
# A test from zdtm/ directory.
|
||||||
#
|
#
|
||||||
@ -384,14 +399,20 @@ class zdtm_test:
|
|||||||
def __make_action(self, act, env=None, root=None):
|
def __make_action(self, act, env=None, root=None):
|
||||||
sys.stdout.flush() # Not to let make's messages appear before ours
|
sys.stdout.flush() # Not to let make's messages appear before ours
|
||||||
tpath = self.__name + '.' + act
|
tpath = self.__name + '.' + act
|
||||||
s_args = ['make', '--no-print-directory',
|
s_args = [
|
||||||
'-C', os.path.dirname(tpath),
|
'make', '--no-print-directory', '-C',
|
||||||
os.path.basename(tpath)]
|
os.path.dirname(tpath),
|
||||||
|
os.path.basename(tpath)
|
||||||
|
]
|
||||||
|
|
||||||
if env:
|
if env:
|
||||||
env = dict(os.environ, **env)
|
env = dict(os.environ, **env)
|
||||||
|
|
||||||
s = subprocess.Popen(s_args, env = env, cwd = root, close_fds = True,
|
s = subprocess.Popen(
|
||||||
|
s_args,
|
||||||
|
env=env,
|
||||||
|
cwd=root,
|
||||||
|
close_fds=True,
|
||||||
preexec_fn=self.__freezer and self.__freezer.attach or None)
|
preexec_fn=self.__freezer and self.__freezer.attach or None)
|
||||||
if act == "pid":
|
if act == "pid":
|
||||||
try_run_hook(self, ["--post-start"])
|
try_run_hook(self, ["--post-start"])
|
||||||
@ -480,8 +501,10 @@ class zdtm_test:
|
|||||||
if self.__pid == 0:
|
if self.__pid == 0:
|
||||||
self.getpid()
|
self.getpid()
|
||||||
|
|
||||||
notify_fdout_path = "/proc/%s/fd/%s" % (self.__pid, env['ZDTM_NOTIFY_FDOUT'])
|
notify_fdout_path = "/proc/%s/fd/%s" % (self.__pid,
|
||||||
notify_fdin_path = "/proc/%s/fd/%s" % (self.__pid, env['ZDTM_NOTIFY_FDIN'])
|
env['ZDTM_NOTIFY_FDOUT'])
|
||||||
|
notify_fdin_path = "/proc/%s/fd/%s" % (self.__pid,
|
||||||
|
env['ZDTM_NOTIFY_FDIN'])
|
||||||
|
|
||||||
print("Send pre-dump notify to %s" % (self.__pid))
|
print("Send pre-dump notify to %s" % (self.__pid))
|
||||||
with open(notify_fdout_path, "rb") as fdout:
|
with open(notify_fdout_path, "rb") as fdout:
|
||||||
@ -516,18 +539,25 @@ class zdtm_test:
|
|||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
def __getcropts(self):
|
def __getcropts(self):
|
||||||
opts = self.__desc.get('opts', '').split() + ["--pidfile", os.path.realpath(self.__pidfile())]
|
opts = self.__desc.get('opts', '').split() + [
|
||||||
|
"--pidfile", os.path.realpath(self.__pidfile())
|
||||||
|
]
|
||||||
if self.__flavor.ns:
|
if self.__flavor.ns:
|
||||||
opts += ["--root", self.__flavor.root]
|
opts += ["--root", self.__flavor.root]
|
||||||
if test_flag(self.__desc, 'crlib'):
|
if test_flag(self.__desc, 'crlib'):
|
||||||
opts += ["-L", os.path.dirname(os.path.realpath(self.__name)) + '/lib']
|
opts += [
|
||||||
|
"-L",
|
||||||
|
os.path.dirname(os.path.realpath(self.__name)) + '/lib'
|
||||||
|
]
|
||||||
return opts
|
return opts
|
||||||
|
|
||||||
def getdopts(self):
|
def getdopts(self):
|
||||||
return self.__getcropts() + self.__freezer.getdopts() + self.__desc.get('dopts', '').split()
|
return self.__getcropts() + self.__freezer.getdopts(
|
||||||
|
) + self.__desc.get('dopts', '').split()
|
||||||
|
|
||||||
def getropts(self):
|
def getropts(self):
|
||||||
return self.__getcropts() + self.__freezer.getropts() + self.__desc.get('ropts', '').split()
|
return self.__getcropts() + self.__freezer.getropts(
|
||||||
|
) + self.__desc.get('ropts', '').split()
|
||||||
|
|
||||||
def unlink_pidfile(self):
|
def unlink_pidfile(self):
|
||||||
self.__pid = 0
|
self.__pid = 0
|
||||||
@ -568,11 +598,13 @@ class zdtm_test:
|
|||||||
subprocess.check_call(["make", "zdtm_ct"])
|
subprocess.check_call(["make", "zdtm_ct"])
|
||||||
if not os.access("zdtm/lib/libzdtmtst.a", os.F_OK):
|
if not os.access("zdtm/lib/libzdtmtst.a", os.F_OK):
|
||||||
subprocess.check_call(["make", "-C", "zdtm/"])
|
subprocess.check_call(["make", "-C", "zdtm/"])
|
||||||
subprocess.check_call(["flock", "zdtm_mount_cgroups.lock", "./zdtm_mount_cgroups"])
|
subprocess.check_call(
|
||||||
|
["flock", "zdtm_mount_cgroups.lock", "./zdtm_mount_cgroups"])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def cleanup():
|
def cleanup():
|
||||||
subprocess.check_call(["flock", "zdtm_mount_cgroups.lock", "./zdtm_umount_cgroups"])
|
subprocess.check_call(
|
||||||
|
["flock", "zdtm_mount_cgroups.lock", "./zdtm_umount_cgroups"])
|
||||||
|
|
||||||
|
|
||||||
def load_module_from_file(name, path):
|
def load_module_from_file(name, path):
|
||||||
@ -601,7 +633,9 @@ class inhfd_test:
|
|||||||
def __get_message(self, i):
|
def __get_message(self, i):
|
||||||
m = self.__messages.get(i, None)
|
m = self.__messages.get(i, None)
|
||||||
if not m:
|
if not m:
|
||||||
m = b"".join([random.choice(string.ascii_letters).encode() for _ in range(10)]) + b"%06d" % i
|
m = b"".join([
|
||||||
|
random.choice(string.ascii_letters).encode() for _ in range(10)
|
||||||
|
]) + b"%06d" % i
|
||||||
self.__messages[i] = m
|
self.__messages[i] = m
|
||||||
return m
|
return m
|
||||||
|
|
||||||
@ -631,7 +665,8 @@ class inhfd_test:
|
|||||||
os.unlink(self.__name + ".out")
|
os.unlink(self.__name + ".out")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
fd = os.open(self.__name + ".out", os.O_WRONLY | os.O_APPEND | os.O_CREAT)
|
fd = os.open(self.__name + ".out",
|
||||||
|
os.O_WRONLY | os.O_APPEND | os.O_CREAT)
|
||||||
os.dup2(fd, 1)
|
os.dup2(fd, 1)
|
||||||
os.dup2(fd, 2)
|
os.dup2(fd, 2)
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
@ -669,7 +704,8 @@ class inhfd_test:
|
|||||||
def stop(self):
|
def stop(self):
|
||||||
fds = set(os.listdir("/proc/%s/fd" % self.__peer_pid))
|
fds = set(os.listdir("/proc/%s/fd" % self.__peer_pid))
|
||||||
if fds != self.__fds:
|
if fds != self.__fds:
|
||||||
raise test_fail_exc("File descriptors mismatch: %s %s" % (fds, self.__fds))
|
raise test_fail_exc("File descriptors mismatch: %s %s" %
|
||||||
|
(fds, self.__fds))
|
||||||
i = 0
|
i = 0
|
||||||
for my_file, _ in self.__files:
|
for my_file, _ in self.__files:
|
||||||
msg = self.__get_message(i)
|
msg = self.__get_message(i)
|
||||||
@ -753,7 +789,8 @@ class groups_test(zdtm_test):
|
|||||||
|
|
||||||
s_args = ['make', '--no-print-directory', '-C', tdir]
|
s_args = ['make', '--no-print-directory', '-C', tdir]
|
||||||
subprocess.check_call(s_args + [tname + '.cleanout'])
|
subprocess.check_call(s_args + [tname + '.cleanout'])
|
||||||
s = subprocess.Popen(s_args + ['--dry-run', tname + '.pid'], stdout = subprocess.PIPE)
|
s = subprocess.Popen(s_args + ['--dry-run', tname + '.pid'],
|
||||||
|
stdout=subprocess.PIPE)
|
||||||
cmd = s.stdout.readlines().pop().strip()
|
cmd = s.stdout.readlines().pop().strip()
|
||||||
s.wait()
|
s.wait()
|
||||||
|
|
||||||
@ -792,15 +829,26 @@ join_ns_file = '/run/netns/zdtm_netns'
|
|||||||
|
|
||||||
class criu_cli:
|
class criu_cli:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run(action, args, criu_bin, fault = None, strace = [], preexec = None, nowait = False):
|
def run(action,
|
||||||
env = dict(os.environ, ASAN_OPTIONS = "log_path=asan.log:disable_coredump=0:detect_leaks=0")
|
args,
|
||||||
|
criu_bin,
|
||||||
|
fault=None,
|
||||||
|
strace=[],
|
||||||
|
preexec=None,
|
||||||
|
nowait=False):
|
||||||
|
env = dict(
|
||||||
|
os.environ,
|
||||||
|
ASAN_OPTIONS="log_path=asan.log:disable_coredump=0:detect_leaks=0")
|
||||||
|
|
||||||
if fault:
|
if fault:
|
||||||
print("Forcing %s fault" % fault)
|
print("Forcing %s fault" % fault)
|
||||||
env['CRIU_FAULT'] = fault
|
env['CRIU_FAULT'] = fault
|
||||||
|
|
||||||
cr = subprocess.Popen(strace + [criu_bin, action, "--no-default-config"] + args,
|
cr = subprocess.Popen(strace +
|
||||||
env = env, close_fds = False, preexec_fn = preexec)
|
[criu_bin, action, "--no-default-config"] + args,
|
||||||
|
env=env,
|
||||||
|
close_fds=False,
|
||||||
|
preexec_fn=preexec)
|
||||||
if nowait:
|
if nowait:
|
||||||
return cr
|
return cr
|
||||||
return cr.wait()
|
return cr.wait()
|
||||||
@ -884,7 +932,13 @@ class criu_rpc:
|
|||||||
raise test_fail_exc('RPC for %s required' % arg)
|
raise test_fail_exc('RPC for %s required' % arg)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run(action, args, criu_bin, fault = None, strace = [], preexec = None, nowait = False):
|
def run(action,
|
||||||
|
args,
|
||||||
|
criu_bin,
|
||||||
|
fault=None,
|
||||||
|
strace=[],
|
||||||
|
preexec=None,
|
||||||
|
nowait=False):
|
||||||
if fault:
|
if fault:
|
||||||
raise test_fail_exc('RPC and FAULT not supported')
|
raise test_fail_exc('RPC and FAULT not supported')
|
||||||
if strace:
|
if strace:
|
||||||
@ -905,7 +959,8 @@ class criu_rpc:
|
|||||||
criu.pre_dump()
|
criu.pre_dump()
|
||||||
elif action == 'restore':
|
elif action == 'restore':
|
||||||
if 'rd' not in ctx:
|
if 'rd' not in ctx:
|
||||||
raise test_fail_exc('RPC Non-detached restore is impossible')
|
raise test_fail_exc(
|
||||||
|
'RPC Non-detached restore is impossible')
|
||||||
|
|
||||||
res = criu.restore()
|
res = criu.restore()
|
||||||
pidf = ctx.get('pidf')
|
pidf = ctx.get('pidf')
|
||||||
@ -1001,7 +1056,8 @@ class criu:
|
|||||||
os.rename(self.__dump_path, newpath)
|
os.rename(self.__dump_path, newpath)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise test_fail_exc("couldn't find dump dir %s" % self.__dump_path)
|
raise test_fail_exc("couldn't find dump dir %s" %
|
||||||
|
self.__dump_path)
|
||||||
|
|
||||||
os.makedirs(self.__dump_path)
|
os.makedirs(self.__dump_path)
|
||||||
|
|
||||||
@ -1012,10 +1068,11 @@ class criu:
|
|||||||
|
|
||||||
def __tls_options(self):
|
def __tls_options(self):
|
||||||
pki_dir = os.path.dirname(os.path.abspath(__file__)) + "/pki"
|
pki_dir = os.path.dirname(os.path.abspath(__file__)) + "/pki"
|
||||||
return ["--tls", "--tls-no-cn-verify",
|
return [
|
||||||
"--tls-key", pki_dir + "/key.pem",
|
"--tls", "--tls-no-cn-verify", "--tls-key", pki_dir + "/key.pem",
|
||||||
"--tls-cert", pki_dir + "/cert.pem",
|
"--tls-cert", pki_dir + "/cert.pem", "--tls-cacert",
|
||||||
"--tls-cacert", pki_dir + "/cacert.pem"]
|
pki_dir + "/cacert.pem"
|
||||||
|
]
|
||||||
|
|
||||||
def __ddir(self):
|
def __ddir(self):
|
||||||
return os.path.join(self.__dump_path, "%d" % self.__iter)
|
return os.path.join(self.__dump_path, "%d" % self.__iter)
|
||||||
@ -1043,7 +1100,10 @@ class criu:
|
|||||||
strace = ["strace", "-o", fname, '-T']
|
strace = ["strace", "-o", fname, '-T']
|
||||||
if action == 'restore':
|
if action == 'restore':
|
||||||
strace += ['-f']
|
strace += ['-f']
|
||||||
s_args += ['--action-script', os.getcwd() + '/../scripts/fake-restore.sh']
|
s_args += [
|
||||||
|
'--action-script',
|
||||||
|
os.getcwd() + '/../scripts/fake-restore.sh'
|
||||||
|
]
|
||||||
|
|
||||||
if self.__script:
|
if self.__script:
|
||||||
s_args += ['--action-script', self.__script]
|
s_args += ['--action-script', self.__script]
|
||||||
@ -1066,7 +1126,8 @@ class criu:
|
|||||||
with open("/proc/sys/kernel/ns_last_pid") as ns_last_pid_fd:
|
with open("/proc/sys/kernel/ns_last_pid") as ns_last_pid_fd:
|
||||||
ns_last_pid = ns_last_pid_fd.read()
|
ns_last_pid = ns_last_pid_fd.read()
|
||||||
|
|
||||||
ret = self.__criu.run(action, s_args, self.__criu_bin, self.__fault, strace, preexec, nowait)
|
ret = self.__criu.run(action, s_args, self.__criu_bin, self.__fault,
|
||||||
|
strace, preexec, nowait)
|
||||||
|
|
||||||
if nowait:
|
if nowait:
|
||||||
os.close(status_fds[1])
|
os.close(status_fds[1])
|
||||||
@ -1075,7 +1136,8 @@ class criu:
|
|||||||
if self.__test.blocking():
|
if self.__test.blocking():
|
||||||
raise test_fail_expected_exc(action)
|
raise test_fail_expected_exc(action)
|
||||||
else:
|
else:
|
||||||
raise test_fail_exc("criu %s exited with %s" % (action, ret))
|
raise test_fail_exc("criu %s exited with %s" %
|
||||||
|
(action, ret))
|
||||||
os.close(status_fds[0])
|
os.close(status_fds[0])
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -1090,19 +1152,23 @@ class criu:
|
|||||||
os.chmod(__ddir, 0o777)
|
os.chmod(__ddir, 0o777)
|
||||||
else:
|
else:
|
||||||
# on restore we move only a log file, because we need images
|
# on restore we move only a log file, because we need images
|
||||||
os.rename(os.path.join(__ddir, log), os.path.join(__ddir, log + ".fail"))
|
os.rename(os.path.join(__ddir, log),
|
||||||
|
os.path.join(__ddir, log + ".fail"))
|
||||||
# restore ns_last_pid to avoid a case when criu gets
|
# restore ns_last_pid to avoid a case when criu gets
|
||||||
# PID of one of restored processes.
|
# PID of one of restored processes.
|
||||||
with open("/proc/sys/kernel/ns_last_pid", "w+") as fd:
|
with open("/proc/sys/kernel/ns_last_pid", "w+") as fd:
|
||||||
fd.write(ns_last_pid)
|
fd.write(ns_last_pid)
|
||||||
# try again without faults
|
# try again without faults
|
||||||
print("Run criu " + action)
|
print("Run criu " + action)
|
||||||
ret = self.__criu.run(action, s_args, self.__criu_bin, False, strace, preexec)
|
ret = self.__criu.run(action, s_args, self.__criu_bin, False,
|
||||||
|
strace, preexec)
|
||||||
grep_errors(os.path.join(__ddir, log))
|
grep_errors(os.path.join(__ddir, log))
|
||||||
if ret == 0:
|
if ret == 0:
|
||||||
return
|
return
|
||||||
rst_succeeded = os.access(os.path.join(__ddir, "restore-succeeded"), os.F_OK)
|
rst_succeeded = os.access(
|
||||||
if self.__test.blocking() or (self.__sat and action == 'restore' and rst_succeeded):
|
os.path.join(__ddir, "restore-succeeded"), os.F_OK)
|
||||||
|
if self.__test.blocking() or (self.__sat and action == 'restore' and
|
||||||
|
rst_succeeded):
|
||||||
raise test_fail_expected_exc(action)
|
raise test_fail_expected_exc(action)
|
||||||
else:
|
else:
|
||||||
raise test_fail_exc("CRIU %s" % action)
|
raise test_fail_exc("CRIU %s" % action)
|
||||||
@ -1114,7 +1180,8 @@ class criu:
|
|||||||
if not self.__show_stats:
|
if not self.__show_stats:
|
||||||
return
|
return
|
||||||
|
|
||||||
subprocess.Popen([self.__crit_bin, "show", self.__stats_file(action)]).wait()
|
subprocess.Popen([self.__crit_bin, "show",
|
||||||
|
self.__stats_file(action)]).wait()
|
||||||
|
|
||||||
def check_pages_counts(self):
|
def check_pages_counts(self):
|
||||||
if not os.access(self.__stats_file("dump"), os.R_OK):
|
if not os.access(self.__stats_file("dump"), os.R_OK):
|
||||||
@ -1124,7 +1191,8 @@ class criu:
|
|||||||
with open(self.__stats_file("dump"), 'rb') as stfile:
|
with open(self.__stats_file("dump"), 'rb') as stfile:
|
||||||
stats = crpc.images.load(stfile)
|
stats = crpc.images.load(stfile)
|
||||||
stent = stats['entries'][0]['dump']
|
stent = stats['entries'][0]['dump']
|
||||||
stats_written = int(stent['shpages_written']) + int(stent['pages_written'])
|
stats_written = int(stent['shpages_written']) + int(
|
||||||
|
stent['pages_written'])
|
||||||
|
|
||||||
real_written = 0
|
real_written = 0
|
||||||
for f in os.listdir(self.__ddir()):
|
for f in os.listdir(self.__ddir()):
|
||||||
@ -1134,7 +1202,8 @@ class criu:
|
|||||||
r_pages = real_written / mmap.PAGESIZE
|
r_pages = real_written / mmap.PAGESIZE
|
||||||
r_off = real_written % mmap.PAGESIZE
|
r_off = real_written % mmap.PAGESIZE
|
||||||
if (stats_written != r_pages) or (r_off != 0):
|
if (stats_written != r_pages) or (r_off != 0):
|
||||||
print("ERROR: bad page counts, stats = %d real = %d(%d)" % (stats_written, r_pages, r_off))
|
print("ERROR: bad page counts, stats = %d real = %d(%d)" %
|
||||||
|
(stats_written, r_pages, r_off))
|
||||||
raise test_fail_exc("page counts mismatch")
|
raise test_fail_exc("page counts mismatch")
|
||||||
|
|
||||||
def dump(self, action, opts=[]):
|
def dump(self, action, opts=[]):
|
||||||
@ -1144,7 +1213,10 @@ class criu:
|
|||||||
|
|
||||||
a_opts = ["-t", self.__test.getpid()]
|
a_opts = ["-t", self.__test.getpid()]
|
||||||
if self.__prev_dump_iter:
|
if self.__prev_dump_iter:
|
||||||
a_opts += ["--prev-images-dir", "../%d" % self.__prev_dump_iter, "--track-mem"]
|
a_opts += [
|
||||||
|
"--prev-images-dir",
|
||||||
|
"../%d" % self.__prev_dump_iter, "--track-mem"
|
||||||
|
]
|
||||||
self.__prev_dump_iter = self.__iter
|
self.__prev_dump_iter = self.__iter
|
||||||
|
|
||||||
if self.__page_server:
|
if self.__page_server:
|
||||||
@ -1154,8 +1226,12 @@ class criu:
|
|||||||
if self.__dedup:
|
if self.__dedup:
|
||||||
ps_opts += ["--auto-dedup"]
|
ps_opts += ["--auto-dedup"]
|
||||||
|
|
||||||
self.__page_server_p = self.__criu_act("page-server", opts = ps_opts, nowait = True)
|
self.__page_server_p = self.__criu_act("page-server",
|
||||||
a_opts += ["--page-server", "--address", "127.0.0.1", "--port", "12345"] + self.__tls
|
opts=ps_opts,
|
||||||
|
nowait=True)
|
||||||
|
a_opts += [
|
||||||
|
"--page-server", "--address", "127.0.0.1", "--port", "12345"
|
||||||
|
] + self.__tls
|
||||||
|
|
||||||
a_opts += self.__test.getdopts()
|
a_opts += self.__test.getdopts()
|
||||||
|
|
||||||
@ -1178,7 +1254,9 @@ class criu:
|
|||||||
if self.__lazy_migrate and action == "dump":
|
if self.__lazy_migrate and action == "dump":
|
||||||
a_opts += ["--lazy-pages", "--port", "12345"] + self.__tls
|
a_opts += ["--lazy-pages", "--port", "12345"] + self.__tls
|
||||||
nowait = True
|
nowait = True
|
||||||
self.__dump_process = self.__criu_act(action, opts = a_opts + opts, nowait = nowait)
|
self.__dump_process = self.__criu_act(action,
|
||||||
|
opts=a_opts + opts,
|
||||||
|
nowait=nowait)
|
||||||
if self.__mdedup and self.__iter > 1:
|
if self.__mdedup and self.__iter > 1:
|
||||||
self.__criu_act("dedup", opts=[])
|
self.__criu_act("dedup", opts=[])
|
||||||
|
|
||||||
@ -1212,9 +1290,6 @@ class criu:
|
|||||||
if self.__dedup:
|
if self.__dedup:
|
||||||
r_opts += ["--auto-dedup"]
|
r_opts += ["--auto-dedup"]
|
||||||
|
|
||||||
if self.__dedup:
|
|
||||||
r_opts += ["--auto-dedup"]
|
|
||||||
|
|
||||||
self.__prev_dump_iter = None
|
self.__prev_dump_iter = None
|
||||||
criu_dir = os.path.dirname(os.getcwd())
|
criu_dir = os.path.dirname(os.getcwd())
|
||||||
if os.getenv("GCOV"):
|
if os.getenv("GCOV"):
|
||||||
@ -1224,14 +1299,21 @@ class criu:
|
|||||||
if self.__lazy_pages or self.__lazy_migrate:
|
if self.__lazy_pages or self.__lazy_migrate:
|
||||||
lp_opts = []
|
lp_opts = []
|
||||||
if self.__remote_lazy_pages or self.__lazy_migrate:
|
if self.__remote_lazy_pages or self.__lazy_migrate:
|
||||||
lp_opts += ["--page-server", "--port", "12345",
|
lp_opts += [
|
||||||
"--address", "127.0.0.1"] + self.__tls
|
"--page-server", "--port", "12345", "--address",
|
||||||
|
"127.0.0.1"
|
||||||
|
] + self.__tls
|
||||||
|
|
||||||
if self.__remote_lazy_pages:
|
if self.__remote_lazy_pages:
|
||||||
ps_opts = ["--pidfile", "ps.pid",
|
ps_opts = [
|
||||||
"--port", "12345", "--lazy-pages"] + self.__tls
|
"--pidfile", "ps.pid", "--port", "12345", "--lazy-pages"
|
||||||
self.__page_server_p = self.__criu_act("page-server", opts = ps_opts, nowait = True)
|
] + self.__tls
|
||||||
self.__lazy_pages_p = self.__criu_act("lazy-pages", opts = lp_opts, nowait = True)
|
self.__page_server_p = self.__criu_act("page-server",
|
||||||
|
opts=ps_opts,
|
||||||
|
nowait=True)
|
||||||
|
self.__lazy_pages_p = self.__criu_act("lazy-pages",
|
||||||
|
opts=lp_opts,
|
||||||
|
nowait=True)
|
||||||
r_opts += ["--lazy-pages"]
|
r_opts += ["--lazy-pages"]
|
||||||
|
|
||||||
if self.__leave_stopped:
|
if self.__leave_stopped:
|
||||||
@ -1246,8 +1328,9 @@ class criu:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check(feature):
|
def check(feature):
|
||||||
return criu_cli.run("check", ["--no-default-config", "-v0",
|
return criu_cli.run(
|
||||||
"--feature", feature], opts['criu_bin']) == 0
|
"check", ["--no-default-config", "-v0", "--feature", feature],
|
||||||
|
opts['criu_bin']) == 0
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def available():
|
def available():
|
||||||
@ -1258,12 +1341,14 @@ class criu:
|
|||||||
def kill(self):
|
def kill(self):
|
||||||
if self.__lazy_pages_p:
|
if self.__lazy_pages_p:
|
||||||
self.__lazy_pages_p.terminate()
|
self.__lazy_pages_p.terminate()
|
||||||
print("criu lazy-pages exited with %s" % self.__lazy_pages_p.wait())
|
print("criu lazy-pages exited with %s" %
|
||||||
|
self.__lazy_pages_p.wait())
|
||||||
grep_errors(os.path.join(self.__ddir(), "lazy-pages.log"))
|
grep_errors(os.path.join(self.__ddir(), "lazy-pages.log"))
|
||||||
self.__lazy_pages_p = None
|
self.__lazy_pages_p = None
|
||||||
if self.__page_server_p:
|
if self.__page_server_p:
|
||||||
self.__page_server_p.terminate()
|
self.__page_server_p.terminate()
|
||||||
print("criu page-server exited with %s" % self.__page_server_p.wait())
|
print("criu page-server exited with %s" %
|
||||||
|
self.__page_server_p.wait())
|
||||||
grep_errors(os.path.join(self.__ddir(), "page-server.log"))
|
grep_errors(os.path.join(self.__ddir(), "page-server.log"))
|
||||||
self.__page_server_p = None
|
self.__page_server_p = None
|
||||||
if self.__dump_process:
|
if self.__dump_process:
|
||||||
@ -1354,6 +1439,7 @@ def cr(cr_api, test, opts):
|
|||||||
|
|
||||||
# Additional checks that can be done outside of test process
|
# Additional checks that can be done outside of test process
|
||||||
|
|
||||||
|
|
||||||
def get_visible_state(test):
|
def get_visible_state(test):
|
||||||
maps = {}
|
maps = {}
|
||||||
files = {}
|
files = {}
|
||||||
@ -1364,9 +1450,11 @@ def get_visible_state(test):
|
|||||||
return ({}, {}, {})
|
return ({}, {}, {})
|
||||||
|
|
||||||
r = re.compile('^[0-9]+$')
|
r = re.compile('^[0-9]+$')
|
||||||
pids = filter(lambda p: r.match(p), os.listdir("/proc/%s/root/proc/" % test.getpid()))
|
pids = filter(lambda p: r.match(p),
|
||||||
|
os.listdir("/proc/%s/root/proc/" % test.getpid()))
|
||||||
for pid in pids:
|
for pid in pids:
|
||||||
files[pid] = set(os.listdir("/proc/%s/root/proc/%s/fd" % (test.getpid(), pid)))
|
files[pid] = set(
|
||||||
|
os.listdir("/proc/%s/root/proc/%s/fd" % (test.getpid(), pid)))
|
||||||
|
|
||||||
cmaps = [[0, 0, ""]]
|
cmaps = [[0, 0, ""]]
|
||||||
last = 0
|
last = 0
|
||||||
@ -1376,7 +1464,8 @@ def get_visible_state(test):
|
|||||||
|
|
||||||
m.append(mp.split()[1])
|
m.append(mp.split()[1])
|
||||||
|
|
||||||
f = "/proc/%s/root/proc/%s/map_files/%s" % (test.getpid(), pid, mp.split()[0])
|
f = "/proc/%s/root/proc/%s/map_files/%s" % (test.getpid(), pid,
|
||||||
|
mp.split()[0])
|
||||||
if os.access(f, os.F_OK):
|
if os.access(f, os.F_OK):
|
||||||
st = os.lstat(f)
|
st = os.lstat(f)
|
||||||
m.append(oct(st.st_mode))
|
m.append(oct(st.st_mode))
|
||||||
@ -1388,12 +1477,16 @@ def get_visible_state(test):
|
|||||||
last += 1
|
last += 1
|
||||||
mapsfd.close()
|
mapsfd.close()
|
||||||
|
|
||||||
maps[pid] = set(map(lambda x: '%x-%x %s' % (x[0], x[1], " ".join(x[2:])), cmaps))
|
maps[pid] = set(
|
||||||
|
map(lambda x: '%x-%x %s' % (x[0], x[1], " ".join(x[2:])), cmaps))
|
||||||
|
|
||||||
cmounts = []
|
cmounts = []
|
||||||
try:
|
try:
|
||||||
r = re.compile(r"^\S+\s\S+\s\S+\s(\S+)\s(\S+)\s(\S+)\s[^-]*?(shared)?[^-]*?(master)?[^-]*?-")
|
r = re.compile(
|
||||||
with open("/proc/%s/root/proc/%s/mountinfo" % (test.getpid(), pid)) as mountinfo:
|
r"^\S+\s\S+\s\S+\s(\S+)\s(\S+)\s(\S+)\s[^-]*?(shared)?[^-]*?(master)?[^-]*?-"
|
||||||
|
)
|
||||||
|
with open("/proc/%s/root/proc/%s/mountinfo" %
|
||||||
|
(test.getpid(), pid)) as mountinfo:
|
||||||
for m in mountinfo:
|
for m in mountinfo:
|
||||||
cmounts.append(r.match(m).groups())
|
cmounts.append(r.match(m).groups())
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
@ -1442,9 +1535,11 @@ def check_visible_state(test, state, opts):
|
|||||||
|
|
||||||
if '--link-remap' in test.getdopts():
|
if '--link-remap' in test.getdopts():
|
||||||
import glob
|
import glob
|
||||||
link_remap_list = glob.glob(os.path.dirname(test.getname()) + '/link_remap*')
|
link_remap_list = glob.glob(
|
||||||
|
os.path.dirname(test.getname()) + '/link_remap*')
|
||||||
if link_remap_list:
|
if link_remap_list:
|
||||||
print("%s: link-remap files left: %s" % (test.getname(), link_remap_list))
|
print("%s: link-remap files left: %s" %
|
||||||
|
(test.getname(), link_remap_list))
|
||||||
raise test_fail_exc("link remaps left")
|
raise test_fail_exc("link remaps left")
|
||||||
|
|
||||||
|
|
||||||
@ -1631,7 +1726,8 @@ def do_run_test(tname, tdesc, flavs, opts):
|
|||||||
cr_api.kill()
|
cr_api.kill()
|
||||||
try_run_hook(t, ["--clean"])
|
try_run_hook(t, ["--clean"])
|
||||||
if cr_api.logs():
|
if cr_api.logs():
|
||||||
add_to_report(cr_api.logs(), tname.replace('/', '_') + "_" + f + "/images")
|
add_to_report(cr_api.logs(),
|
||||||
|
tname.replace('/', '_') + "_" + f + "/images")
|
||||||
if opts['keep_img'] == 'never':
|
if opts['keep_img'] == 'never':
|
||||||
cr_api.cleanup()
|
cr_api.cleanup()
|
||||||
# When option --keep-going not specified this exit
|
# When option --keep-going not specified this exit
|
||||||
@ -1672,9 +1768,12 @@ class Launcher:
|
|||||||
att = 0
|
att = 0
|
||||||
reportname = os.path.join(report_dir, "criu-testreport.tap")
|
reportname = os.path.join(report_dir, "criu-testreport.tap")
|
||||||
junitreport = os.path.join(report_dir, "criu-testreport.xml")
|
junitreport = os.path.join(report_dir, "criu-testreport.xml")
|
||||||
while os.access(reportname, os.F_OK) or os.access(junitreport, os.F_OK):
|
while os.access(reportname, os.F_OK) or os.access(
|
||||||
reportname = os.path.join(report_dir, "criu-testreport" + ".%d.tap" % att)
|
junitreport, os.F_OK):
|
||||||
junitreport = os.path.join(report_dir, "criu-testreport" + ".%d.xml" % att)
|
reportname = os.path.join(report_dir,
|
||||||
|
"criu-testreport" + ".%d.tap" % att)
|
||||||
|
junitreport = os.path.join(report_dir,
|
||||||
|
"criu-testreport" + ".%d.xml" % att)
|
||||||
att += 1
|
att += 1
|
||||||
|
|
||||||
self.__junit_file = open(junitreport, 'a')
|
self.__junit_file = open(junitreport, 'a')
|
||||||
@ -1683,7 +1782,9 @@ class Launcher:
|
|||||||
self.__file_report = open(reportname, 'a')
|
self.__file_report = open(reportname, 'a')
|
||||||
print(u"TAP version 13", file=self.__file_report)
|
print(u"TAP version 13", file=self.__file_report)
|
||||||
print(u"# Hardware architecture: " + arch, file=self.__file_report)
|
print(u"# Hardware architecture: " + arch, file=self.__file_report)
|
||||||
print(u"# Timestamp: " + now.strftime("%Y-%m-%d %H:%M") + " (GMT+1)", file=self.__file_report)
|
print(u"# Timestamp: " + now.strftime("%Y-%m-%d %H:%M") +
|
||||||
|
" (GMT+1)",
|
||||||
|
file=self.__file_report)
|
||||||
print(u"# ", file=self.__file_report)
|
print(u"# ", file=self.__file_report)
|
||||||
print(u"1.." + str(nr_tests), file=self.__file_report)
|
print(u"1.." + str(nr_tests), file=self.__file_report)
|
||||||
with open("/proc/sys/kernel/tainted") as taintfd:
|
with open("/proc/sys/kernel/tainted") as taintfd:
|
||||||
@ -1695,7 +1796,8 @@ class Launcher:
|
|||||||
|
|
||||||
def __show_progress(self, msg):
|
def __show_progress(self, msg):
|
||||||
perc = int(self.__nr * 16 / self.__total)
|
perc = int(self.__nr * 16 / self.__total)
|
||||||
print("=== Run %d/%d %s %s" % (self.__nr, self.__total, '=' * perc + '-' * (16 - perc), msg))
|
print("=== Run %d/%d %s %s" %
|
||||||
|
(self.__nr, self.__total, '=' * perc + '-' * (16 - perc), msg))
|
||||||
|
|
||||||
def skip(self, name, reason):
|
def skip(self, name, reason):
|
||||||
print("Skipping %s (%s)" % (name, reason))
|
print("Skipping %s (%s)" % (name, reason))
|
||||||
@ -1719,7 +1821,8 @@ class Launcher:
|
|||||||
with open("/proc/sys/kernel/tainted") as taintfd:
|
with open("/proc/sys/kernel/tainted") as taintfd:
|
||||||
taint = taintfd.read()
|
taint = taintfd.read()
|
||||||
if self.__taint != taint:
|
if self.__taint != taint:
|
||||||
raise Exception("The kernel is tainted: %r (%r)" % (taint, self.__taint))
|
raise Exception("The kernel is tainted: %r (%r)" %
|
||||||
|
(taint, self.__taint))
|
||||||
|
|
||||||
if test_flag(desc, 'excl'):
|
if test_flag(desc, 'excl'):
|
||||||
self.wait_all()
|
self.wait_all()
|
||||||
@ -1727,11 +1830,12 @@ class Launcher:
|
|||||||
self.__nr += 1
|
self.__nr += 1
|
||||||
self.__show_progress(name)
|
self.__show_progress(name)
|
||||||
|
|
||||||
nd = ('nocr', 'norst', 'pre', 'iters', 'page_server', 'sibling', 'stop', 'empty_ns',
|
nd = ('nocr', 'norst', 'pre', 'iters', 'page_server', 'sibling',
|
||||||
'fault', 'keep_img', 'report', 'snaps', 'sat', 'script', 'rpc', 'lazy_pages',
|
'stop', 'empty_ns', 'fault', 'keep_img', 'report', 'snaps',
|
||||||
'join_ns', 'dedup', 'sbs', 'freezecg', 'user', 'dry_run', 'noauto_dedup',
|
'sat', 'script', 'rpc', 'lazy_pages', 'join_ns', 'dedup', 'sbs',
|
||||||
'remote_lazy_pages', 'show_stats', 'lazy_migrate', 'tls',
|
'freezecg', 'user', 'dry_run', 'noauto_dedup',
|
||||||
'criu_bin', 'crit_bin')
|
'remote_lazy_pages', 'show_stats', 'lazy_migrate',
|
||||||
|
'tls', 'criu_bin', 'crit_bin')
|
||||||
arg = repr((name, desc, flavor, {d: self.__opts[d] for d in nd}))
|
arg = repr((name, desc, flavor, {d: self.__opts[d] for d in nd}))
|
||||||
|
|
||||||
if self.__use_log:
|
if self.__use_log:
|
||||||
@ -1743,8 +1847,15 @@ class Launcher:
|
|||||||
|
|
||||||
sub = subprocess.Popen(["./zdtm_ct", "zdtm.py"],
|
sub = subprocess.Popen(["./zdtm_ct", "zdtm.py"],
|
||||||
env=dict(os.environ, CR_CT_TEST_INFO=arg),
|
env=dict(os.environ, CR_CT_TEST_INFO=arg),
|
||||||
stdout = log, stderr = subprocess.STDOUT, close_fds = True)
|
stdout=log,
|
||||||
self.__subs[sub.pid] = {'sub': sub, 'log': logf, 'name': name, "start": time.time()}
|
stderr=subprocess.STDOUT,
|
||||||
|
close_fds=True)
|
||||||
|
self.__subs[sub.pid] = {
|
||||||
|
'sub': sub,
|
||||||
|
'log': logf,
|
||||||
|
'name': name,
|
||||||
|
"start": time.time()
|
||||||
|
}
|
||||||
|
|
||||||
if test_flag(desc, 'excl'):
|
if test_flag(desc, 'excl'):
|
||||||
self.wait()
|
self.wait()
|
||||||
@ -1771,21 +1882,26 @@ class Launcher:
|
|||||||
sub = self.__subs.pop(pid)
|
sub = self.__subs.pop(pid)
|
||||||
tc = None
|
tc = None
|
||||||
if self.__junit_test_cases is not None:
|
if self.__junit_test_cases is not None:
|
||||||
tc = TestCase(sub['name'], elapsed_sec=time.time() - sub['start'])
|
tc = TestCase(sub['name'],
|
||||||
|
elapsed_sec=time.time() - sub['start'])
|
||||||
self.__junit_test_cases.append(tc)
|
self.__junit_test_cases.append(tc)
|
||||||
if status != 0:
|
if status != 0:
|
||||||
self.__fail = True
|
self.__fail = True
|
||||||
failed_flavor = decode_flav(os.WEXITSTATUS(status))
|
failed_flavor = decode_flav(os.WEXITSTATUS(status))
|
||||||
self.__failed.append([sub['name'], failed_flavor])
|
self.__failed.append([sub['name'], failed_flavor])
|
||||||
if self.__file_report:
|
if self.__file_report:
|
||||||
testline = u"not ok %d - %s # flavor %s" % (self.__runtest, sub['name'], failed_flavor)
|
testline = u"not ok %d - %s # flavor %s" % (
|
||||||
|
self.__runtest, sub['name'], failed_flavor)
|
||||||
with open(sub['log']) as sublog:
|
with open(sub['log']) as sublog:
|
||||||
output = sublog.read()
|
output = sublog.read()
|
||||||
details = {'output': output}
|
details = {'output': output}
|
||||||
tc.add_error_info(output=output)
|
tc.add_error_info(output=output)
|
||||||
print(testline, file=self.__file_report)
|
print(testline, file=self.__file_report)
|
||||||
print("%s" % yaml.safe_dump(details, explicit_start=True,
|
print("%s" % yaml.safe_dump(details,
|
||||||
explicit_end=True, default_style='|'), file=self.__file_report)
|
explicit_start=True,
|
||||||
|
explicit_end=True,
|
||||||
|
default_style='|'),
|
||||||
|
file=self.__file_report)
|
||||||
if sub['log']:
|
if sub['log']:
|
||||||
add_to_output(sub['log'])
|
add_to_output(sub['log'])
|
||||||
else:
|
else:
|
||||||
@ -1795,7 +1911,8 @@ class Launcher:
|
|||||||
|
|
||||||
if sub['log']:
|
if sub['log']:
|
||||||
with open(sub['log']) as sublog:
|
with open(sub['log']) as sublog:
|
||||||
print("%s" % sublog.read().encode('ascii', 'ignore').decode('utf-8'))
|
print("%s" % sublog.read().encode(
|
||||||
|
'ascii', 'ignore').decode('utf-8'))
|
||||||
os.unlink(sub['log'])
|
os.unlink(sub['log'])
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -1824,20 +1941,23 @@ class Launcher:
|
|||||||
if not opts['fault'] and check_core_files():
|
if not opts['fault'] and check_core_files():
|
||||||
self.__fail = True
|
self.__fail = True
|
||||||
if self.__file_report:
|
if self.__file_report:
|
||||||
ts = TestSuite(opts['title'], self.__junit_test_cases, os.getenv("NODE_NAME"))
|
ts = TestSuite(opts['title'], self.__junit_test_cases,
|
||||||
|
os.getenv("NODE_NAME"))
|
||||||
self.__junit_file.write(TestSuite.to_xml_string([ts]))
|
self.__junit_file.write(TestSuite.to_xml_string([ts]))
|
||||||
self.__junit_file.close()
|
self.__junit_file.close()
|
||||||
self.__file_report.close()
|
self.__file_report.close()
|
||||||
|
|
||||||
if opts['keep_going']:
|
if opts['keep_going']:
|
||||||
if self.__fail:
|
if self.__fail:
|
||||||
print_sep("%d TEST(S) FAILED (TOTAL %d/SKIPPED %d)"
|
print_sep(
|
||||||
% (len(self.__failed), self.__total, self.__nr_skip), "#")
|
"%d TEST(S) FAILED (TOTAL %d/SKIPPED %d)" %
|
||||||
|
(len(self.__failed), self.__total, self.__nr_skip), "#")
|
||||||
for failed in self.__failed:
|
for failed in self.__failed:
|
||||||
print(" * %s(%s)" % (failed[0], failed[1]))
|
print(" * %s(%s)" % (failed[0], failed[1]))
|
||||||
else:
|
else:
|
||||||
print_sep("ALL TEST(S) PASSED (TOTAL %d/SKIPPED %d)"
|
print_sep(
|
||||||
% (self.__total, self.__nr_skip), "#")
|
"ALL TEST(S) PASSED (TOTAL %d/SKIPPED %d)" %
|
||||||
|
(self.__total, self.__nr_skip), "#")
|
||||||
|
|
||||||
if self.__fail:
|
if self.__fail:
|
||||||
print_sep("FAIL", "#")
|
print_sep("FAIL", "#")
|
||||||
@ -1860,12 +1980,9 @@ def all_tests(opts):
|
|||||||
continue
|
continue
|
||||||
files.append(fp)
|
files.append(fp)
|
||||||
excl = list(map(lambda x: os.path.join(desc['dir'], x), desc['exclude']))
|
excl = list(map(lambda x: os.path.join(desc['dir'], x), desc['exclude']))
|
||||||
tlist = filter(lambda x:
|
tlist = filter(
|
||||||
not x.endswith('.checkskip') and
|
lambda x: not x.endswith('.checkskip') and not x.endswith('.hook') and
|
||||||
not x.endswith('.hook') and
|
x not in excl, map(lambda x: x.strip(), files))
|
||||||
x not in excl,
|
|
||||||
map(lambda x: x.strip(), files)
|
|
||||||
)
|
|
||||||
return tlist
|
return tlist
|
||||||
|
|
||||||
|
|
||||||
@ -1966,7 +2083,9 @@ def run_tests(opts):
|
|||||||
|
|
||||||
torun = list(torun)
|
torun = list(torun)
|
||||||
if opts['keep_going'] and len(torun) < 2:
|
if opts['keep_going'] and len(torun) < 2:
|
||||||
print("[WARNING] Option --keep-going is more useful when running multiple tests")
|
print(
|
||||||
|
"[WARNING] Option --keep-going is more useful when running multiple tests"
|
||||||
|
)
|
||||||
opts['keep_going'] = False
|
opts['keep_going'] = False
|
||||||
|
|
||||||
if opts['exclude']:
|
if opts['exclude']:
|
||||||
@ -1983,17 +2102,23 @@ def run_tests(opts):
|
|||||||
if opts['join_ns']:
|
if opts['join_ns']:
|
||||||
if subprocess.Popen(["ip", "netns", "add", "zdtm_netns"]).wait():
|
if subprocess.Popen(["ip", "netns", "add", "zdtm_netns"]).wait():
|
||||||
raise Exception("Unable to create a network namespace")
|
raise Exception("Unable to create a network namespace")
|
||||||
if subprocess.Popen(["ip", "netns", "exec", "zdtm_netns", "ip", "link", "set", "up", "dev", "lo"]).wait():
|
if subprocess.Popen([
|
||||||
|
"ip", "netns", "exec", "zdtm_netns", "ip", "link", "set", "up",
|
||||||
|
"dev", "lo"
|
||||||
|
]).wait():
|
||||||
raise Exception("ip link set up dev lo")
|
raise Exception("ip link set up dev lo")
|
||||||
|
|
||||||
if opts['lazy_pages'] or opts['remote_lazy_pages'] or opts['lazy_migrate']:
|
if opts['lazy_pages'] or opts['remote_lazy_pages'] or opts['lazy_migrate']:
|
||||||
uffd = criu.check("uffd")
|
uffd = criu.check("uffd")
|
||||||
uffd_noncoop = criu.check("uffd-noncoop")
|
uffd_noncoop = criu.check("uffd-noncoop")
|
||||||
if not uffd:
|
if not uffd:
|
||||||
raise Exception("UFFD is not supported, cannot run with --lazy-pages")
|
raise Exception(
|
||||||
|
"UFFD is not supported, cannot run with --lazy-pages")
|
||||||
if not uffd_noncoop:
|
if not uffd_noncoop:
|
||||||
# Most tests will work with 4.3 - 4.11
|
# Most tests will work with 4.3 - 4.11
|
||||||
print("[WARNING] Non-cooperative UFFD is missing, some tests might spuriously fail")
|
print(
|
||||||
|
"[WARNING] Non-cooperative UFFD is missing, some tests might spuriously fail"
|
||||||
|
)
|
||||||
|
|
||||||
launcher = Launcher(opts, len(torun))
|
launcher = Launcher(opts, len(torun))
|
||||||
try:
|
try:
|
||||||
@ -2047,7 +2172,8 @@ def run_tests(opts):
|
|||||||
launcher.skip(t, "samens test in the same namespace")
|
launcher.skip(t, "samens test in the same namespace")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if opts['lazy_pages'] or opts['remote_lazy_pages'] or opts['lazy_migrate']:
|
if opts['lazy_pages'] or opts['remote_lazy_pages'] or opts[
|
||||||
|
'lazy_migrate']:
|
||||||
if test_flag(tdesc, 'nolazy'):
|
if test_flag(tdesc, 'nolazy'):
|
||||||
launcher.skip(t, "lazy pages are not supported")
|
launcher.skip(t, "lazy pages are not supported")
|
||||||
continue
|
continue
|
||||||
@ -2137,8 +2263,7 @@ class group:
|
|||||||
# which will call all tests' scripts in turn
|
# which will call all tests' scripts in turn
|
||||||
def __dump_meta(self, fname, ext):
|
def __dump_meta(self, fname, ext):
|
||||||
scripts = filter(lambda names: os.access(names[1], os.X_OK),
|
scripts = filter(lambda names: os.access(names[1], os.X_OK),
|
||||||
map(lambda test: (test, test + ext),
|
map(lambda test: (test, test + ext), self.__tests))
|
||||||
self.__tests))
|
|
||||||
if scripts:
|
if scripts:
|
||||||
f = open(fname + ext, "w")
|
f = open(fname + ext, "w")
|
||||||
f.write("#!/bin/sh -e\n")
|
f.write("#!/bin/sh -e\n")
|
||||||
@ -2250,7 +2375,9 @@ if 'CR_CT_TEST_INFO' in os.environ:
|
|||||||
sys.exit(status)
|
sys.exit(status)
|
||||||
|
|
||||||
p = argparse.ArgumentParser("CRIU test suite")
|
p = argparse.ArgumentParser("CRIU test suite")
|
||||||
p.add_argument("--debug", help = "Print what's being executed", action = 'store_true')
|
p.add_argument("--debug",
|
||||||
|
help="Print what's being executed",
|
||||||
|
action='store_true')
|
||||||
p.add_argument("--set", help="Which set of tests to use", default='zdtm')
|
p.add_argument("--set", help="Which set of tests to use", default='zdtm')
|
||||||
|
|
||||||
sp = p.add_subparsers(help="Use --help for list of actions")
|
sp = p.add_subparsers(help="Use --help for list of actions")
|
||||||
@ -2262,53 +2389,115 @@ rp.add_argument("-t", "--test", help = "Test name", action = 'append')
|
|||||||
rp.add_argument("-T", "--tests", help="Regexp")
|
rp.add_argument("-T", "--tests", help="Regexp")
|
||||||
rp.add_argument("-F", "--from", help="From file")
|
rp.add_argument("-F", "--from", help="From file")
|
||||||
rp.add_argument("-f", "--flavor", help="Flavor to run")
|
rp.add_argument("-f", "--flavor", help="Flavor to run")
|
||||||
rp.add_argument("-x", "--exclude", help = "Exclude tests from --all run", action = 'append')
|
rp.add_argument("-x",
|
||||||
|
"--exclude",
|
||||||
|
help="Exclude tests from --all run",
|
||||||
|
action='append')
|
||||||
|
|
||||||
rp.add_argument("--sibling", help = "Restore tests as siblings", action = 'store_true')
|
rp.add_argument("--sibling",
|
||||||
rp.add_argument("--join-ns", help = "Restore tests and join existing namespace", action = 'store_true')
|
help="Restore tests as siblings",
|
||||||
rp.add_argument("--empty-ns", help = "Restore tests in empty net namespace", action = 'store_true')
|
action='store_true')
|
||||||
|
rp.add_argument("--join-ns",
|
||||||
|
help="Restore tests and join existing namespace",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--empty-ns",
|
||||||
|
help="Restore tests in empty net namespace",
|
||||||
|
action='store_true')
|
||||||
rp.add_argument("--pre", help="Do some pre-dumps before dump (n[:pause])")
|
rp.add_argument("--pre", help="Do some pre-dumps before dump (n[:pause])")
|
||||||
rp.add_argument("--snaps", help = "Instead of pre-dumps do full dumps", action = 'store_true')
|
rp.add_argument("--snaps",
|
||||||
rp.add_argument("--dedup", help = "Auto-deduplicate images on iterations", action = 'store_true')
|
help="Instead of pre-dumps do full dumps",
|
||||||
rp.add_argument("--noauto-dedup", help = "Manual deduplicate images on iterations", action = 'store_true')
|
action='store_true')
|
||||||
rp.add_argument("--nocr", help = "Do not CR anything, just check test works", action = 'store_true')
|
rp.add_argument("--dedup",
|
||||||
rp.add_argument("--norst", help = "Don't restore tasks, leave them running after dump", action = 'store_true')
|
help="Auto-deduplicate images on iterations",
|
||||||
rp.add_argument("--stop", help = "Check that --leave-stopped option stops ps tree.", action = 'store_true')
|
action='store_true')
|
||||||
rp.add_argument("--iters", help = "Do CR cycle several times before check (n[:pause])")
|
rp.add_argument("--noauto-dedup",
|
||||||
|
help="Manual deduplicate images on iterations",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--nocr",
|
||||||
|
help="Do not CR anything, just check test works",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--norst",
|
||||||
|
help="Don't restore tasks, leave them running after dump",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--stop",
|
||||||
|
help="Check that --leave-stopped option stops ps tree.",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--iters",
|
||||||
|
help="Do CR cycle several times before check (n[:pause])")
|
||||||
rp.add_argument("--fault", help="Test fault injection")
|
rp.add_argument("--fault", help="Test fault injection")
|
||||||
rp.add_argument("--sat", help = "Generate criu strace-s for sat tool (restore is fake, images are kept)", action = 'store_true')
|
rp.add_argument(
|
||||||
rp.add_argument("--sbs", help = "Do step-by-step execution, asking user for keypress to continue", action = 'store_true')
|
"--sat",
|
||||||
|
help="Generate criu strace-s for sat tool (restore is fake, images are kept)",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument(
|
||||||
|
"--sbs",
|
||||||
|
help="Do step-by-step execution, asking user for keypress to continue",
|
||||||
|
action='store_true')
|
||||||
rp.add_argument("--freezecg", help="Use freeze cgroup (path:state)")
|
rp.add_argument("--freezecg", help="Use freeze cgroup (path:state)")
|
||||||
rp.add_argument("--user", help="Run CRIU as regular user", action='store_true')
|
rp.add_argument("--user", help="Run CRIU as regular user", action='store_true')
|
||||||
rp.add_argument("--rpc", help = "Run CRIU via RPC rather than CLI", action = 'store_true')
|
rp.add_argument("--rpc",
|
||||||
|
help="Run CRIU via RPC rather than CLI",
|
||||||
|
action='store_true')
|
||||||
|
|
||||||
rp.add_argument("--page-server", help = "Use page server dump", action = 'store_true')
|
rp.add_argument("--page-server",
|
||||||
|
help="Use page server dump",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--remote",
|
||||||
|
help="Use remote option for diskless C/R",
|
||||||
|
action='store_true')
|
||||||
rp.add_argument("-p", "--parallel", help="Run test in parallel")
|
rp.add_argument("-p", "--parallel", help="Run test in parallel")
|
||||||
rp.add_argument("--dry-run", help="Don't run tests, just pretend to", action='store_true')
|
rp.add_argument("--dry-run",
|
||||||
|
help="Don't run tests, just pretend to",
|
||||||
|
action='store_true')
|
||||||
rp.add_argument("--script", help="Add script to get notified by criu")
|
rp.add_argument("--script", help="Add script to get notified by criu")
|
||||||
rp.add_argument("-k", "--keep-img", help = "Whether or not to keep images after test",
|
rp.add_argument("-k",
|
||||||
choices = ['always', 'never', 'failed'], default = 'failed')
|
"--keep-img",
|
||||||
|
help="Whether or not to keep images after test",
|
||||||
|
choices=['always', 'never', 'failed'],
|
||||||
|
default='failed')
|
||||||
rp.add_argument("--report", help="Generate summary report in directory")
|
rp.add_argument("--report", help="Generate summary report in directory")
|
||||||
rp.add_argument("--keep-going", help = "Keep running tests in spite of failures", action = 'store_true')
|
rp.add_argument("--keep-going",
|
||||||
rp.add_argument("--ignore-taint", help = "Don't care about a non-zero kernel taint flag", action = 'store_true')
|
help="Keep running tests in spite of failures",
|
||||||
rp.add_argument("--lazy-pages", help = "restore pages on demand", action = 'store_true')
|
action='store_true')
|
||||||
rp.add_argument("--lazy-migrate", help = "restore pages on demand", action = 'store_true')
|
rp.add_argument("--ignore-taint",
|
||||||
rp.add_argument("--remote-lazy-pages", help = "simulate lazy migration", action = 'store_true')
|
help="Don't care about a non-zero kernel taint flag",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--lazy-pages",
|
||||||
|
help="restore pages on demand",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--lazy-migrate",
|
||||||
|
help="restore pages on demand",
|
||||||
|
action='store_true')
|
||||||
|
rp.add_argument("--remote-lazy-pages",
|
||||||
|
help="simulate lazy migration",
|
||||||
|
action='store_true')
|
||||||
rp.add_argument("--tls", help="use TLS for migration", action='store_true')
|
rp.add_argument("--tls", help="use TLS for migration", action='store_true')
|
||||||
rp.add_argument("--title", help="A test suite title", default="criu")
|
rp.add_argument("--title", help="A test suite title", default="criu")
|
||||||
rp.add_argument("--show-stats", help = "Show criu statistics", action = 'store_true')
|
rp.add_argument("--show-stats",
|
||||||
rp.add_argument("--criu-bin", help = "Path to criu binary", default = '../criu/criu')
|
help="Show criu statistics",
|
||||||
rp.add_argument("--crit-bin", help = "Path to crit binary", default = '../crit/crit')
|
action='store_true')
|
||||||
|
rp.add_argument("--criu-bin",
|
||||||
|
help="Path to criu binary",
|
||||||
|
default='../criu/criu')
|
||||||
|
rp.add_argument("--crit-bin",
|
||||||
|
help="Path to crit binary",
|
||||||
|
default='../crit/crit')
|
||||||
|
|
||||||
lp = sp.add_parser("list", help="List tests")
|
lp = sp.add_parser("list", help="List tests")
|
||||||
lp.set_defaults(action=list_tests)
|
lp.set_defaults(action=list_tests)
|
||||||
lp.add_argument('-i', '--info', help = "Show more info about tests", action = 'store_true')
|
lp.add_argument('-i',
|
||||||
|
'--info',
|
||||||
|
help="Show more info about tests",
|
||||||
|
action='store_true')
|
||||||
|
|
||||||
gp = sp.add_parser("group", help="Generate groups")
|
gp = sp.add_parser("group", help="Generate groups")
|
||||||
gp.set_defaults(action=group_tests)
|
gp.set_defaults(action=group_tests)
|
||||||
gp.add_argument("-m", "--max-size", help="Maximum number of tests in group")
|
gp.add_argument("-m", "--max-size", help="Maximum number of tests in group")
|
||||||
gp.add_argument("-n", "--name", help="Common name for group tests")
|
gp.add_argument("-n", "--name", help="Common name for group tests")
|
||||||
gp.add_argument("-x", "--exclude", help = "Exclude tests from --all run", action = 'append')
|
gp.add_argument("-x",
|
||||||
|
"--exclude",
|
||||||
|
help="Exclude tests from --all run",
|
||||||
|
action='append')
|
||||||
|
|
||||||
cp = sp.add_parser("clean", help="Clean something")
|
cp = sp.add_parser("clean", help="Clean something")
|
||||||
cp.set_defaults(action=clean_stuff)
|
cp.set_defaults(action=clean_stuff)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user