2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 09:58:09 +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:
Andrei Vagin 2019-09-07 15:46:22 +03:00
parent 5ff4fcb753
commit 5aa72e7237
28 changed files with 5738 additions and 5167 deletions

View File

@ -36,29 +36,26 @@ from pycriu import images
# Some memory-related constants
PAGESIZE = 4096
status = {
"VMA_AREA_NONE" : 0 << 0,
"VMA_AREA_REGULAR" : 1 << 0,
"VMA_AREA_STACK" : 1 << 1,
"VMA_AREA_VSYSCALL" : 1 << 2,
"VMA_AREA_VDSO" : 1 << 3,
"VMA_FORCE_READ" : 1 << 4,
"VMA_AREA_HEAP" : 1 << 5,
"VMA_FILE_PRIVATE" : 1 << 6,
"VMA_FILE_SHARED" : 1 << 7,
"VMA_ANON_SHARED" : 1 << 8,
"VMA_ANON_PRIVATE" : 1 << 9,
"VMA_AREA_SYSVIPC" : 1 << 10,
"VMA_AREA_SOCKET" : 1 << 11,
"VMA_AREA_VVAR" : 1 << 12,
"VMA_AREA_AIORING" : 1 << 13,
"VMA_AREA_UNSUPP" : 1 << 31
"VMA_AREA_NONE": 0 << 0,
"VMA_AREA_REGULAR": 1 << 0,
"VMA_AREA_STACK": 1 << 1,
"VMA_AREA_VSYSCALL": 1 << 2,
"VMA_AREA_VDSO": 1 << 3,
"VMA_FORCE_READ": 1 << 4,
"VMA_AREA_HEAP": 1 << 5,
"VMA_FILE_PRIVATE": 1 << 6,
"VMA_FILE_SHARED": 1 << 7,
"VMA_ANON_SHARED": 1 << 8,
"VMA_ANON_PRIVATE": 1 << 9,
"VMA_AREA_SYSVIPC": 1 << 10,
"VMA_AREA_SOCKET": 1 << 11,
"VMA_AREA_VVAR": 1 << 12,
"VMA_AREA_AIORING": 1 << 13,
"VMA_AREA_UNSUPP": 1 << 31
}
prot = {
"PROT_READ" : 0x1,
"PROT_WRITE" : 0x2,
"PROT_EXEC" : 0x4
}
prot = {"PROT_READ": 0x1, "PROT_WRITE": 0x2, "PROT_EXEC": 0x4}
class elf_note:
nhdr = None # Elf_Nhdr;
@ -75,6 +72,7 @@ class coredump:
phdrs = [] # Array of Phdrs;
notes = [] # Array of elf_notes;
vmas = [] # Array of BytesIO with memory content;
# FIXME keeping all vmas in memory is a bad idea;
def write(self, f):
@ -90,11 +88,11 @@ class coredump:
for note in self.notes:
buf.write(note.nhdr)
buf.write(note.owner)
buf.write("\0"*(8-len(note.owner)))
buf.write("\0" * (8 - len(note.owner)))
buf.write(note.data)
offset = ctypes.sizeof(elf.Elf64_Ehdr())
offset += (len(self.vmas) + 1)*ctypes.sizeof(elf.Elf64_Phdr())
offset += (len(self.vmas) + 1) * ctypes.sizeof(elf.Elf64_Phdr())
filesz = 0
for note in self.notes:
@ -129,13 +127,13 @@ class coredump_generator:
reg_files = None # reg-files;
pagemaps = {} # pagemap by pid;
def _img_open_and_strip(self, name, single = False, pid = None):
def _img_open_and_strip(self, name, single=False, pid=None):
"""
Load criu image and strip it from magic and redundant list.
"""
path = self._imgs_dir + "/" + name
if pid:
path += "-"+str(pid)
path += "-" + str(pid)
path += ".img"
with open(path) as f:
@ -146,7 +144,6 @@ class coredump_generator:
else:
return img["entries"]
def __call__(self, imgs_dir):
"""
Parse criu images stored in directory imgs_dir to fill core dumps.
@ -161,18 +158,18 @@ class coredump_generator:
for tid in p['threads']:
self.cores[tid] = self._img_open_and_strip("core", True, tid)
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)
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"]
for pid in self.pstree:
self.coredumps[pid] = self._gen_coredump(pid)
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
core dump of only one process.
@ -180,7 +177,7 @@ class coredump_generator:
for p in self.coredumps:
if pid and p != pid:
continue
with open(coredumps_dir+"/"+"core."+str(p), 'w+') as f:
with open(coredumps_dir + "/" + "core." + str(p), 'w+') as f:
self.coredumps[p].write(f)
def _gen_coredump(self, pid):
@ -231,7 +228,7 @@ class coredump_generator:
phdrs = []
offset = ctypes.sizeof(elf.Elf64_Ehdr())
offset += (len(vmas) + 1)*ctypes.sizeof(elf.Elf64_Phdr())
offset += (len(vmas) + 1) * ctypes.sizeof(elf.Elf64_Phdr())
filesz = 0
for note in notes:
@ -298,9 +295,11 @@ class coredump_generator:
prpsinfo.pr_state = 3
# Don't even ask me why it is so, just borrowed from linux
# 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_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_uid = core["thread_core"]["creds"]["uid"]
prpsinfo.pr_gid = core["thread_core"]["creds"]["gid"]
@ -399,8 +398,10 @@ class coredump_generator:
fpregset.rdp = regs["rdp"]
fpregset.mxcsr = regs["mxcsr"]
fpregset.mxcr_mask = regs["mxcsr_mask"]
fpregset.st_space = (ctypes.c_uint * len(regs["st_space"]))(*regs["st_space"])
fpregset.xmm_space = (ctypes.c_uint * len(regs["xmm_space"]))(*regs["xmm_space"])
fpregset.st_space = (ctypes.c_uint * len(regs["st_space"]))(
*regs["st_space"])
fpregset.xmm_space = (ctypes.c_uint * len(regs["xmm_space"]))(
*regs["xmm_space"])
#fpregset.padding = regs["padding"] unused
nhdr = elf.Elf64_Nhdr()
@ -433,12 +434,16 @@ class coredump_generator:
data.i387.rdp = fpregs["rdp"]
data.i387.mxcsr = fpregs["mxcsr"]
data.i387.mxcsr_mask = fpregs["mxcsr_mask"]
data.i387.st_space = (ctypes.c_uint * len(fpregs["st_space"]))(*fpregs["st_space"])
data.i387.xmm_space = (ctypes.c_uint * len(fpregs["xmm_space"]))(*fpregs["xmm_space"])
data.i387.st_space = (ctypes.c_uint * len(fpregs["st_space"]))(
*fpregs["st_space"])
data.i387.xmm_space = (ctypes.c_uint * len(fpregs["xmm_space"]))(
*fpregs["xmm_space"])
if "xsave" in fpregs:
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.n_namesz = 6
@ -477,15 +482,15 @@ class coredump_generator:
Generate NT_AUXV note for thread tid of process pid.
"""
mm = self.mms[pid]
num_auxv = len(mm["mm_saved_auxv"])/2
num_auxv = len(mm["mm_saved_auxv"]) / 2
class elf_auxv(ctypes.Structure):
_fields_ = [("auxv", elf.Elf64_auxv_t*num_auxv)]
_fields_ = [("auxv", elf.Elf64_auxv_t * num_auxv)]
auxv = elf_auxv()
for i in range(num_auxv):
auxv.auxv[i].a_type = mm["mm_saved_auxv"][i]
auxv.auxv[i].a_val = mm["mm_saved_auxv"][i+1]
auxv.auxv[i].a_val = mm["mm_saved_auxv"][i + 1]
nhdr = elf.Elf64_Nhdr()
nhdr.n_namesz = 5
@ -519,7 +524,7 @@ class coredump_generator:
shmid = vma["shmid"]
size = vma["end"] - vma["start"]
off = vma["pgoff"]/PAGESIZE
off = vma["pgoff"] / PAGESIZE
files = self.reg_files
fname = filter(lambda x: x["id"] == shmid, files)[0]["name"]
@ -547,11 +552,12 @@ class coredump_generator:
fields.append(("count", ctypes.c_long))
fields.append(("page_size", ctypes.c_long))
for i in range(len(infos)):
fields.append(("start"+str(i), ctypes.c_long))
fields.append(("end"+str(i), ctypes.c_long))
fields.append(("file_ofs"+str(i), ctypes.c_long))
fields.append(("start" + str(i), ctypes.c_long))
fields.append(("end" + str(i), ctypes.c_long))
fields.append(("file_ofs" + str(i), ctypes.c_long))
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):
_fields_ = fields
@ -561,14 +567,14 @@ class coredump_generator:
data.page_size = PAGESIZE
for i in range(len(infos)):
info = infos[i]
setattr(data, "start"+str(i), info.start)
setattr(data, "end"+str(i), info.end)
setattr(data, "file_ofs"+str(i), info.file_ofs)
setattr(data, "name"+str(i), info.name)
setattr(data, "start" + str(i), info.start)
setattr(data, "end" + str(i), info.end)
setattr(data, "file_ofs" + str(i), info.file_ofs)
setattr(data, "name" + str(i), info.name)
nhdr = elf.Elf64_Nhdr()
nhdr.n_namesz = 5#XXX strlen + 1
nhdr.n_namesz = 5 #XXX strlen + 1
nhdr.n_descsz = ctypes.sizeof(elf_files())
nhdr.n_type = elf.NT_FILE
@ -623,11 +629,11 @@ class coredump_generator:
# First entry is pagemap_head, we will need it later to open
# proper pages.img.
pages_id = pagemap[0]["pages_id"]
off = 0# in pages
off = 0 # in pages
for m in pagemap[1:]:
found = False
for i in range(m["nr_pages"]):
if m["vaddr"] + i*PAGESIZE == page_no*PAGESIZE:
if m["vaddr"] + i * PAGESIZE == page_no * PAGESIZE:
found = True
break
off += 1
@ -639,8 +645,9 @@ class coredump_generator:
ppid = self.pstree[pid]["ppid"]
return self._get_page(ppid, page_no)
else:
with open(self._imgs_dir+"/"+"pages-"+str(pages_id)+".img") as f:
f.seek(off*PAGESIZE)
with open(self._imgs_dir + "/" + "pages-" + str(pages_id) +
".img") as f:
f.seek(off * PAGESIZE)
return f.read(PAGESIZE)
return None
@ -657,11 +664,11 @@ class coredump_generator:
if vma["status"] & status["VMA_AREA_VVAR"]:
#FIXME this is what gdb does, as vvar vma
# is not readable from userspace?
return "\0"*size
return "\0" * size
elif vma["status"] & status["VMA_AREA_VSYSCALL"]:
#FIXME need to dump it with criu or read from
# current process.
return "\0"*size
return "\0" * size
if vma["status"] & status["VMA_FILE_SHARED"] or \
vma["status"] & status["VMA_FILE_PRIVATE"]:
@ -694,11 +701,11 @@ class coredump_generator:
# a file, and changed ones -- from pages.img.
# Finally, if no page is found neither in pages.img nor
# in file, hole in inserted -- a page filled with zeroes.
start_page = start/PAGESIZE
end_page = end/PAGESIZE
start_page = start / PAGESIZE
end_page = end / PAGESIZE
buf = ""
for page_no in range(start_page, end_page+1):
for page_no in range(start_page, end_page + 1):
page = None
# Search for needed page in pages.img and reg-files.img
@ -715,24 +722,24 @@ class coredump_generator:
if page == None:
# Hole
page = PAGESIZE*"\0"
page = PAGESIZE * "\0"
# If it is a start or end page, we need to read
# only part of it.
if page_no == start_page:
n_skip = start - page_no*PAGESIZE
n_skip = start - page_no * PAGESIZE
if start_page == end_page:
n_read = size
else:
n_read = PAGESIZE - n_skip
elif page_no == end_page:
n_skip = 0
n_read = end - page_no*PAGESIZE
n_read = end - page_no * PAGESIZE
else:
n_skip = 0
n_read = PAGESIZE
buf += page[n_skip : n_skip + n_read]
buf += page[n_skip:n_skip + n_read]
# Don't forget to close file.
if f != None:

View File

@ -16,13 +16,16 @@ EI_MAG0 = 0 # #define EI_MAG0 0 /* File identification b
ELFMAG0 = 0x7f # #define ELFMAG0 0x7f /* Magic number byte 0 */
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 */
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 */
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 */
@ -43,9 +46,11 @@ EM_X86_64 = 62 # #define EM_X86_64 62 /* AMD x86-64 architec
# Legal values for e_version (version).
EV_CURRENT = 1 # #define EV_CURRENT 1 /* Current version */
class Elf64_Ehdr(ctypes.Structure): # typedef struct
_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_machine", Elf64_Half), # Elf64_Half e_machine;
("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_R = 1 << 2 # #define PF_R (1 << 2) /* Segment is readable */
class Elf64_Phdr(ctypes.Structure): # typedef struct
_fields_ = [ # {
("p_type", Elf64_Word), # Elf64_Word p_type;
@ -88,14 +94,15 @@ class Elf64_Phdr(ctypes.Structure): # typedef struct
# Elf64_auxv_t related constants.
class _Elf64_auxv_t_U(ctypes.Union):
_fields_ = [
("a_val", ctypes.c_uint64)
]
_fields_ = [("a_val", ctypes.c_uint64)]
class Elf64_auxv_t(ctypes.Structure): # typedef struct
_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
# {
# uint64_t a_val; /* Integer value */
@ -118,101 +125,178 @@ NT_FILE = 0x46494c45 # #define NT_FILE 0x46494c45 /* Contains info
# files */
NT_X86_XSTATE = 0x202 # #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
class Elf64_Nhdr(ctypes.Structure): # typedef struct
_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_type", Elf64_Word), # Elf64_Word n_type; /* Type of the note. */
(
"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_type", Elf64_Word
), # Elf64_Word n_type; /* Type of the note. */
] # } Elf64_Nhdr;
# Elf64_Shdr related constants.
class Elf64_Shdr(ctypes.Structure): # typedef struct
_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_flags", Elf64_Xword), # Elf64_Xword sh_flags; /* Section flags */
("sh_addr", Elf64_Addr), # 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 */
(
"sh_name", Elf64_Word
), # Elf64_Word sh_name; /* Section name (string tbl index) */
("sh_type", Elf64_Word
), # Elf64_Word sh_type; /* Section type */
("sh_flags", Elf64_Xword
), # Elf64_Xword sh_flags; /* Section flags */
(
"sh_addr", Elf64_Addr
), # 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;
# elf_prstatus related constants.
# Signal info.
class elf_siginfo(ctypes.Structure): # struct elf_siginfo
_fields_ = [ # {
("si_signo", ctypes.c_int), # int si_signo; /* Signal number. */
("si_code", ctypes.c_int), # int si_code; /* Extra code. */
("si_errno", ctypes.c_int) # int si_errno; /* Errno. */
("si_signo", ctypes.c_int
), # int si_signo; /* Signal number. */
("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
# microsecond but also has a range of years.
class timeval(ctypes.Structure): # struct timeval
_fields_ = [ # {
("tv_sec", ctypes.c_long), # __time_t tv_sec; /* Seconds. */
("tv_usec", ctypes.c_long) # __suseconds_t tv_usec; /* Microseconds. */
("tv_sec",
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
_fields_ = [ # {
("r15", ctypes.c_ulonglong), # __extension__ unsigned long long int r15;
("r14", ctypes.c_ulonglong), # __extension__ unsigned long long int r14;
("r13", ctypes.c_ulonglong), # __extension__ unsigned long long int r13;
("r12", ctypes.c_ulonglong), # __extension__ unsigned long long int r12;
("rbp", ctypes.c_ulonglong), # __extension__ unsigned long long int rbp;
("rbx", ctypes.c_ulonglong), # __extension__ unsigned long long int rbx;
("r11", ctypes.c_ulonglong), # __extension__ unsigned long long int r11;
("r10", ctypes.c_ulonglong), # __extension__ unsigned long long int r10;
("r9", ctypes.c_ulonglong), # __extension__ unsigned long long int r9;
("r8", ctypes.c_ulonglong), # __extension__ unsigned long long int r8;
("rax", ctypes.c_ulonglong), # __extension__ unsigned long long int rax;
("rcx", ctypes.c_ulonglong), # __extension__ unsigned long long int rcx;
("rdx", ctypes.c_ulonglong), # __extension__ unsigned long long int rdx;
("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;
("r15",
ctypes.c_ulonglong), # __extension__ unsigned long long int r15;
("r14",
ctypes.c_ulonglong), # __extension__ unsigned long long int r14;
("r13",
ctypes.c_ulonglong), # __extension__ unsigned long long int r13;
("r12",
ctypes.c_ulonglong), # __extension__ unsigned long long int r12;
("rbp",
ctypes.c_ulonglong), # __extension__ unsigned long long int rbp;
("rbx",
ctypes.c_ulonglong), # __extension__ unsigned long long int rbx;
("r11",
ctypes.c_ulonglong), # __extension__ unsigned long long int r11;
("r10",
ctypes.c_ulonglong), # __extension__ unsigned long long int r10;
("r9",
ctypes.c_ulonglong), # __extension__ unsigned long long int r9;
("r8",
ctypes.c_ulonglong), # __extension__ unsigned long long int r8;
("rax",
ctypes.c_ulonglong), # __extension__ unsigned long long int rax;
("rcx",
ctypes.c_ulonglong), # __extension__ unsigned long long int rcx;
("rdx",
ctypes.c_ulonglong), # __extension__ unsigned long long int rdx;
("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_NGREG = ctypes.sizeof(user_regs_struct)/ctypes.sizeof(elf_greg_t)
#elf_gregset_t = elf_greg_t*ELF_NGREG
elf_gregset_t = user_regs_struct
class elf_prstatus(ctypes.Structure): # struct elf_prstatus
_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_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_info", elf_siginfo
), # struct elf_siginfo pr_info; /* Info associated with signal. */
("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_ppid", ctypes.c_int), # __pid_t pr_ppid;
("pr_pgrp", ctypes.c_int), # __pid_t pr_pgrp;
("pr_sid", ctypes.c_int), # __pid_t pr_sid;
("pr_utime", timeval), # struct timeval pr_utime; /* User time. */
("pr_stime", timeval), # struct timeval pr_stime; /* System time. */
("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. */
("pr_utime",
timeval), # struct timeval pr_utime; /* User time. */
("pr_stime", timeval
), # struct timeval pr_stime; /* System time. */
(
"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. */
class elf_prpsinfo(ctypes.Structure): # struct elf_prpsinfo
_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_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. */
(
"pr_state", ctypes.c_byte
), # char pr_state; /* Numeric process state. */
(
"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
# unsigned short int pr_uid;
# unsigned short int pr_gid;
@ -239,8 +331,12 @@ class elf_prpsinfo(ctypes.Structure): # struct elf_prpsinfo
("pr_pgrp", ctypes.c_int),
("pr_sid", ctypes.c_int),
# /* 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;
("ftw", ctypes.c_ushort), # unsigned short int ftw;
("fop", ctypes.c_ushort), # unsigned short int fop;
("rip", ctypes.c_ulonglong), # __extension__ unsigned long long int rip;
("rdp", ctypes.c_ulonglong), # __extension__ unsigned long long int rdp;
("rip",
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;
("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 */
("padding", ctypes.c_uint*24), # unsigned int padding[24];
(
"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 */
("padding",
ctypes.c_uint * 24), # unsigned int padding[24];
] # };
elf_fpregset_t = user_fpregs_struct
# siginfo_t related constants.
_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
_fields_ = [ # {
("si_pid", ctypes.c_int), # __pid_t si_pid; /* Sending process ID. */
("si_uid", ctypes.c_uint) # __uid_t si_uid; /* Real user ID of sending process. */
("si_pid", ctypes.c_int
), # __pid_t si_pid; /* Sending process ID. */
(
"si_uid", ctypes.c_uint
) # __uid_t si_uid; /* Real user ID of sending process. */
] # } _kill;
# Type for data associated with a signal.
class sigval_t(ctypes.Union): # typedef union sigval
_fields_ = [ # {
@ -284,45 +389,63 @@ class sigval_t(ctypes.Union): # typedef union sigval
("sical_ptr", ctypes.c_void_p), # void *sival_ptr;
] # } sigval_t;
# /* POSIX.1b timers. */
class _siginfo_t_U_timer(ctypes.Structure): # struct
_fields_ = [ # {
("si_tid", ctypes.c_int), # int si_tid; /* Timer ID. */
("si_overrun", ctypes.c_int), # int si_overrun; /* Overrun count. */
("si_sigval", sigval_t) # sigval_t si_sigval; /* Signal value. */
("si_tid",
ctypes.c_int), # int si_tid; /* Timer ID. */
("si_overrun", ctypes.c_int
), # int si_overrun; /* Overrun count. */
("si_sigval", sigval_t
) # sigval_t si_sigval; /* Signal value. */
] # } _timer;
# /* POSIX.1b signals. */
class _siginfo_t_U_rt(ctypes.Structure): # struct
_fields_ = [ # {
("si_pid", ctypes.c_int), # __pid_t si_pid; /* Sending process ID. */
("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. */
("si_pid", ctypes.c_int
), # __pid_t si_pid; /* Sending process ID. */
(
"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;
# /* SIGCHLD. */
class _siginfo_t_U_sigchld(ctypes.Structure): # struct
_fields_ = [ # {
("si_pid", ctypes.c_int), # __pid_t si_pid; /* Which child. */
("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_pid",
ctypes.c_int), # __pid_t si_pid; /* Which child. */
(
"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_stime", ctypes.c_long) # __sigchld_clock_t si_stime;
] # } _sigchld;
# /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
class _siginfo_t_U_sigfault(ctypes.Structure): # struct
_fields_ = [ # {
("si_addr", ctypes.c_void_p), # void *si_addr; /* Faulting insn/memory ref. */
("si_addr_lsb", ctypes.c_short) # short int si_addr_lsb; /* Valid LSB of the reported address. */
("si_addr", ctypes.c_void_p
), # 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;
# /* SIGPOLL. */
class _siginfo_t_U_sigpoll(ctypes.Structure): # struct
_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;
] # } _sigpoll;
@ -330,15 +453,20 @@ class _siginfo_t_U_sigpoll(ctypes.Structure): # struct
# /* SIGSYS. */
class _siginfo_t_U_sigsys(ctypes.Structure): # struct
_fields_ = [ # {
("_call_addr", ctypes.c_void_p), # void *_call_addr; /* Calling user insn. */
("_syscall", ctypes.c_int), # int _syscall; /* Triggering system call number. */
("_arch", ctypes.c_uint) # unsigned int _arch; /* AUDIT_ARCH_* of syscall. */
("_call_addr", ctypes.c_void_p
), # void *_call_addr; /* Calling user insn. */
(
"_syscall", ctypes.c_int
), # int _syscall; /* Triggering system call number. */
("_arch", ctypes.c_uint
) # unsigned int _arch; /* AUDIT_ARCH_* of syscall. */
] # } _sigsys;
class _siginfo_t_U(ctypes.Union): # union
_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", _siginfo_t_U_kill), # struct
@ -396,12 +524,17 @@ class _siginfo_t_U(ctypes.Union): # union
# } _sigsys;
] # } _sifields;
class siginfo_t(ctypes.Structure): # typedef struct
_fields_ = [ # {
("si_signo", ctypes.c_int), # int si_signo; /* Signal number. */
("si_errno", ctypes.c_int), # int si_errno; /* If non-zero, an errno value associated with
("si_signo", ctypes.c_int
), # 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>. */
("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
# {
@ -467,30 +600,46 @@ class siginfo_t(ctypes.Structure): # typedef struct
# xsave related.
class ymmh_struct(ctypes.Structure): # struct ymmh_struct {
_fields_ = [
("ymmh_space", 64*ctypes.c_uint) # u32 ymmh_space[64];
_fields_ = [("ymmh_space", 64 * ctypes.c_uint
) # u32 ymmh_space[64];
] # } __packed;
class xsave_hdr_struct(ctypes.Structure): # struct xsave_hdr_struct {
_fields_ = [
("xstate_bv", ctypes.c_ulonglong), # u64 xstate_bv;
("reserved1", ctypes.c_ulonglong*2), # u64 reserved1[2];
("reserved2", ctypes.c_ulonglong*5) # u64 reserved2[5];
("xstate_bv", ctypes.c_ulonglong
), # u64 xstate_bv;
("reserved1", ctypes.c_ulonglong *
2), # u64 reserved1[2];
("reserved2", ctypes.c_ulonglong * 5
) # u64 reserved2[5];
] # } __packed;
class i387_fxsave_struct(ctypes.Structure): # struct i387_fxsave_struct {
_fields_ = [
("cwd", ctypes.c_ushort), # u16 cwd; /* Control Word */
("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 */
(
"cwd", ctypes.c_ushort
), # u16 cwd; /* Control Word */
(
"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 {
# 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 {
# u32 fip; /* FPU IP Offset */
@ -499,19 +648,27 @@ class i387_fxsave_struct(ctypes.Structure): # struct i387_fxsave_struct {
# 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 */
("st_space", ctypes.c_uint*32), # u32 st_space[32];
#
# /* 16*16 bytes for each XMM-reg = 256 bytes */
("xmm_space", ctypes.c_uint*64), # u32 xmm_space[64];
("st_space", ctypes.c_uint * 32
), # u32 st_space[32];
#
("padding", ctypes.c_uint*12), # u32 padding[12];
# /* 16*16 bytes for each XMM-reg = 256 bytes */
("xmm_space", ctypes.c_uint * 64
), # u32 xmm_space[64];
#
("padding", ctypes.c_uint * 12
), # u32 padding[12];
#
# union {
("padding1", ctypes.c_uint*12) # u32 padding1[12];
("padding1", ctypes.c_uint * 12
) # u32 padding1[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 {
_fields_ = [
("i387", i387_fxsave_struct), # struct i387_fxsave_struct i387;
("xsave_hdr", xsave_hdr_struct), # struct xsave_hdr_struct xsave_hdr;
("i387",
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;
] # } __aligned(FP_MIN_ALIGN_BYTES) __packed;

View File

@ -6,21 +6,25 @@ import os
import pycriu
def inf(opts):
if opts['in']:
return open(opts['in'], 'rb')
else:
return sys.stdin
def outf(opts):
if opts['out']:
return open(opts['out'], 'w+')
else:
return sys.stdout
def dinf(opts, name):
return open(os.path.join(opts['dir'], name))
def decode(opts):
indent = None
@ -40,21 +44,27 @@ def decode(opts):
if f == sys.stdout:
f.write("\n")
def encode(opts):
img = json.load(inf(opts))
pycriu.images.dump(img, outf(opts))
def info(opts):
infs = pycriu.images.info(inf(opts))
json.dump(infs, sys.stdout, indent = 4)
json.dump(infs, sys.stdout, indent=4)
print()
def get_task_id(p, val):
return p[val] if val in p else p['ns_' + val][0]
#
# Explorers
#
class ps_item:
def __init__(self, p, core):
self.pid = get_task_id(p, 'pid')
@ -63,17 +73,21 @@ class ps_item:
self.core = core
self.kids = []
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'),
' ' * (4 * depth), p.core['tc']['comm']))
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'), ' ' *
(4 * depth), p.core['tc']['comm']))
for kid in p.kids:
show_ps(kid, opts, depth + 1)
def explore_ps(opts):
pss = { }
pss = {}
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
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])
pss[ps.pid] = ps
@ -91,8 +105,10 @@ def explore_ps(opts):
print("%7s%7s%7s %s" % ('PID', 'PGID', 'SID', 'COMM'))
show_ps(psr, opts)
files_img = None
def ftype_find_in_files(opts, ft, fid):
global files_img
@ -124,14 +140,17 @@ def ftype_find_in_image(opts, ft, fid, img):
return f
return None
def ftype_reg(opts, ft, fid):
rf = ftype_find_in_image(opts, ft, fid, 'reg-files.img')
return rf and rf['name'] or 'unknown path'
def ftype_pipe(opts, ft, fid):
p = ftype_find_in_image(opts, ft, fid, 'pipes.img')
return p and 'pipe[%d]' % p['pipe_id'] or 'pipe[?]'
def ftype_unix(opts, ft, fid):
ux = ftype_find_in_image(opts, ft, fid, 'unixsk.img')
if not ux:
@ -140,16 +159,32 @@ def ftype_unix(opts, ft, fid):
n = ux['name'] and ' %s' % ux['name'] or ''
return 'unix[%d (%d)%s]' % (ux['ino'], ux['peer'], n)
file_types = {
'REG': {'get': ftype_reg, 'img': None, 'field': 'reg'},
'PIPE': {'get': ftype_pipe, 'img': None, 'field': 'pipe'},
'UNIXSK': {'get': ftype_unix, 'img': None, 'field': 'usk'},
'REG': {
'get': ftype_reg,
'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):
return '%s.%d' % (ft['typ'], fid)
files_cache = { }
files_cache = {}
def get_file_str(opts, fd):
key = (fd['type'], fd['id'])
@ -161,6 +196,7 @@ def get_file_str(opts, fd):
return f
def explore_fds(opts):
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
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)))
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" % ('root', get_file_str(opts, {'type': 'REG', 'id': fdi['root_id']})))
print("\t%7s: %s" %
('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:
@ -192,6 +236,7 @@ class vma_id:
return ret
def explore_mems(opts):
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
vids = vma_id()
@ -200,7 +245,11 @@ def explore_mems(opts):
mmi = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]
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']:
st = vma['status']
@ -211,7 +260,10 @@ def explore_mems(opts):
elif st & (1 << 11):
fn = ' ' + 'packet[%lx]' % vids.get(vma['shmid'])
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']:
fn += ' + %#lx' % vma['pgoff']
if st & (1 << 7):
@ -242,7 +294,8 @@ def explore_rss(opts):
ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
for p in ps_img['entries']:
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']
print("%d" % pid)
@ -260,9 +313,13 @@ def explore_rss(opts):
if vmi == pvmi:
vstr += ' ~'
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)):
vstr += ' ' + get_file_str(opts, {'type': 'REG', 'id': vma['shmid']})
vstr += ' ' + get_file_str(opts, {
'type': 'REG',
'id': vma['shmid']
})
pvmi = vmi
vstr += '\n\t%23s' % ''
vmi += 1
@ -272,61 +329,75 @@ def explore_rss(opts):
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):
explorers[opts['what']](opts)
def main():
desc = 'CRiu Image Tool'
parser = argparse.ArgumentParser(description=desc,
formatter_class=argparse.RawTextHelpFormatter)
parser = argparse.ArgumentParser(
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_parser = subparsers.add_parser('decode',
help = 'convert criu image from binary type to json')
decode_parser.add_argument('--pretty',
help = 'Multiline with indents and some numerical fields in field-specific format',
action = 'store_true')
decode_parser.add_argument('-i',
decode_parser = subparsers.add_parser(
'decode', help='convert criu image from binary type to json')
decode_parser.add_argument(
'--pretty',
help=
'Multiline with indents and some numerical fields in field-specific format',
action='store_true')
decode_parser.add_argument(
'-i',
'--in',
help = 'criu image in binary format to be decoded (stdin by default)')
decode_parser.add_argument('-o',
help='criu image in binary format to be decoded (stdin by default)')
decode_parser.add_argument(
'-o',
'--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)
# Encode
encode_parser = subparsers.add_parser('encode',
help = 'convert criu image from json type to binary')
encode_parser.add_argument('-i',
encode_parser = subparsers.add_parser(
'encode', help='convert criu image from json type to binary')
encode_parser.add_argument(
'-i',
'--in',
help = 'criu image in json format to be encoded (stdin by default)')
encode_parser.add_argument('-o',
help='criu image in json format to be encoded (stdin by default)')
encode_parser.add_argument(
'-o',
'--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)
# Info
info_parser = subparsers.add_parser('info',
help = 'show info about image')
info_parser = subparsers.add_parser('info', help='show info about image')
info_parser.add_argument("in")
info_parser.set_defaults(func=info)
# Explore
x_parser = subparsers.add_parser('x', help = 'explore image dir')
x_parser = subparsers.add_parser('x', help='explore image dir')
x_parser.add_argument('dir')
x_parser.add_argument('what', choices = [ 'ps', 'fds', 'mems', 'rss'])
x_parser.add_argument('what', choices=['ps', 'fds', 'mems', 'rss'])
x_parser.set_defaults(func=explore)
# Show
show_parser = subparsers.add_parser('show',
help = "convert criu image from binary to human-readable json")
show_parser = subparsers.add_parser(
'show', help="convert criu image from binary to human-readable json")
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)
opts = vars(parser.parse_args())
@ -338,5 +409,6 @@ def main():
opts["func"](opts)
if __name__ == '__main__':
main()

View File

@ -8,6 +8,7 @@ import struct
import pycriu.rpc_pb2 as rpc
class _criu_comm:
"""
Base class for communication classes.
@ -37,6 +38,7 @@ class _criu_comm_sk(_criu_comm):
"""
Communication class for unix socket.
"""
def __init__(self, sk_path):
self.comm_type = self.COMM_SK
self.comm = sk_path
@ -55,22 +57,26 @@ class _criu_comm_fd(_criu_comm):
"""
Communication class for file descriptor.
"""
def __init__(self, fd):
self.comm_type = self.COMM_FD
self.comm = fd
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
def disconnect(self):
self.sk.close()
class _criu_comm_bin(_criu_comm):
"""
Communication class for binary.
"""
def __init__(self, bin_path):
self.comm_type = self.COMM_BIN
self.comm = bin_path
@ -90,13 +96,16 @@ class _criu_comm_bin(_criu_comm):
p = os.fork()
if p == 0:
def exec_criu():
os.close(0)
os.close(1)
os.close(2)
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)
if daemon:
@ -143,9 +152,11 @@ class CRIUExceptionInternal(CRIUException):
"""
Exception class for handling and storing internal errors.
"""
def __init__(self, typ, s):
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):

View File

@ -57,14 +57,17 @@ sizeof_u16 = 2
sizeof_u32 = 4
sizeof_u64 = 8
# A helper for rounding
def round_up(x,y):
def round_up(x, y):
return (((x - 1) | (y - 1)) + 1)
class MagicException(Exception):
def __init__(self, magic):
self.magic = magic
# Generic class to handle loading/dumping criu images entries from/to bin
# format to/from dict(json).
class entry_handler:
@ -72,6 +75,7 @@ class entry_handler:
Generic class to handle loading/dumping criu images
entries from/to bin format to/from dict(json).
"""
def __init__(self, payload, extra_handler=None):
"""
Sets payload class and extra handler class.
@ -79,7 +83,7 @@ class entry_handler:
self.payload = payload
self.extra_handler = extra_handler
def load(self, f, pretty = False, no_payload = False):
def load(self, f, pretty=False, no_payload=False):
"""
Convert criu image entries from binary format to dict(json).
Takes a file-like object and returnes a list with entries in
@ -102,8 +106,9 @@ class entry_handler:
# Read extra
if self.extra_handler:
if no_payload:
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 int(num) == num:
return "%d%sB" % (num, unit)
@ -121,7 +126,7 @@ class entry_handler:
return entries
def loads(self, s, pretty = False):
def loads(self, s, pretty=False):
"""
Same as load(), but takes a string as an argument.
"""
@ -174,6 +179,7 @@ class entry_handler:
return entries
# Special handler for pagemap.img
class pagemap_handler:
"""
@ -181,7 +187,8 @@ class pagemap_handler:
that it has a header of pagemap_head type followed by entries
of pagemap_entry type.
"""
def load(self, f, pretty = False, no_payload = False):
def load(self, f, pretty=False, no_payload=False):
entries = []
pbuff = pb.pagemap_head()
@ -197,7 +204,7 @@ class pagemap_handler:
return entries
def loads(self, s, pretty = False):
def loads(self, s, pretty=False):
f = io.BytesIO(s)
return self.load(f, pretty)
@ -220,9 +227,10 @@ class pagemap_handler:
def count(self, f):
return entry_handler(None).count(f) - 1
# Special handler for ghost-file.img
class ghost_file_handler:
def load(self, f, pretty = False, no_payload = False):
def load(self, f, pretty=False, no_payload=False):
entries = []
gf = pb.ghost_file_entry()
@ -255,7 +263,7 @@ class ghost_file_handler:
return entries
def loads(self, s, pretty = False):
def loads(self, s, pretty=False):
f = io.BytesIO(s)
return self.load(f, pretty)
@ -306,6 +314,7 @@ class pipes_data_extra_handler:
f.seek(pload.bytes, os.SEEK_CUR)
return pload.bytes
class sk_queues_extra_handler:
def load(self, f, pload):
size = pload.length
@ -344,6 +353,7 @@ class tcp_stream_extra_handler:
f.seek(0, os.SEEK_END)
return pbuff.inq_len + pbuff.outq_len
class ipc_sem_set_handler:
def load(self, f, pbuff):
entry = pb2dict.pb2dict(pbuff)
@ -375,11 +385,12 @@ class ipc_sem_set_handler:
f.seek(round_up(size, sizeof_u64), os.SEEK_CUR)
return size
class ipc_msg_queue_handler:
def load(self, f, pbuff):
entry = pb2dict.pb2dict(pbuff)
messages = []
for x in range (0, entry['qnum']):
for x in range(0, entry['qnum']):
buf = f.read(4)
if buf == '':
break
@ -395,7 +406,7 @@ class ipc_msg_queue_handler:
def dump(self, extra, f, pbuff):
entry = pb2dict.pb2dict(pbuff)
for i in range (0, len(extra), 2):
for i in range(0, len(extra), 2):
msg = pb.ipc_msg()
pb2dict.dict2pb(extra[i], msg)
msg_str = msg.SerializeToString()
@ -410,7 +421,7 @@ class ipc_msg_queue_handler:
def skip(self, f, pbuff):
entry = pb2dict.pb2dict(pbuff)
pl_len = 0
for x in range (0, entry['qnum']):
for x in range(0, entry['qnum']):
buf = f.read(4)
if buf == '':
break
@ -423,6 +434,7 @@ class ipc_msg_queue_handler:
return pl_len
class ipc_shm_handler:
def load(self, f, pbuff):
entry = pb2dict.pb2dict(pbuff)
@ -449,71 +461,75 @@ class ipc_shm_handler:
handlers = {
'INVENTORY' : entry_handler(pb.inventory_entry),
'CORE' : entry_handler(pb.core_entry),
'IDS' : entry_handler(pb.task_kobj_ids_entry),
'CREDS' : entry_handler(pb.creds_entry),
'UTSNS' : entry_handler(pb.utsns_entry),
'IPC_VAR' : entry_handler(pb.ipc_var_entry),
'FS' : entry_handler(pb.fs_entry),
'GHOST_FILE' : ghost_file_handler(),
'MM' : entry_handler(pb.mm_entry),
'CGROUP' : entry_handler(pb.cgroup_entry),
'TCP_STREAM' : entry_handler(pb.tcp_stream_entry, tcp_stream_extra_handler()),
'STATS' : entry_handler(pb.stats_entry),
'PAGEMAP' : pagemap_handler(), # Special one
'PSTREE' : entry_handler(pb.pstree_entry),
'REG_FILES' : entry_handler(pb.reg_file_entry),
'NS_FILES' : entry_handler(pb.ns_file_entry),
'EVENTFD_FILE' : entry_handler(pb.eventfd_file_entry),
'EVENTPOLL_FILE' : entry_handler(pb.eventpoll_file_entry),
'EVENTPOLL_TFD' : entry_handler(pb.eventpoll_tfd_entry),
'SIGNALFD' : entry_handler(pb.signalfd_entry),
'TIMERFD' : entry_handler(pb.timerfd_entry),
'INOTIFY_FILE' : entry_handler(pb.inotify_file_entry),
'INOTIFY_WD' : entry_handler(pb.inotify_wd_entry),
'FANOTIFY_FILE' : entry_handler(pb.fanotify_file_entry),
'FANOTIFY_MARK' : entry_handler(pb.fanotify_mark_entry),
'VMAS' : entry_handler(pb.vma_entry),
'PIPES' : entry_handler(pb.pipe_entry),
'FIFO' : entry_handler(pb.fifo_entry),
'SIGACT' : entry_handler(pb.sa_entry),
'NETLINK_SK' : entry_handler(pb.netlink_sk_entry),
'REMAP_FPATH' : entry_handler(pb.remap_file_path_entry),
'MNTS' : entry_handler(pb.mnt_entry),
'TTY_FILES' : entry_handler(pb.tty_file_entry),
'TTY_INFO' : entry_handler(pb.tty_info_entry),
'TTY_DATA' : entry_handler(pb.tty_data_entry),
'RLIMIT' : entry_handler(pb.rlimit_entry),
'TUNFILE' : entry_handler(pb.tunfile_entry),
'EXT_FILES' : entry_handler(pb.ext_file_entry),
'IRMAP_CACHE' : entry_handler(pb.irmap_cache_entry),
'FILE_LOCKS' : entry_handler(pb.file_lock_entry),
'FDINFO' : entry_handler(pb.fdinfo_entry),
'UNIXSK' : entry_handler(pb.unix_sk_entry),
'INETSK' : entry_handler(pb.inet_sk_entry),
'PACKETSK' : entry_handler(pb.packet_sock_entry),
'ITIMERS' : entry_handler(pb.itimer_entry),
'POSIX_TIMERS' : entry_handler(pb.posix_timer_entry),
'NETDEV' : entry_handler(pb.net_device_entry),
'PIPES_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()),
'IPCNS_SHM' : entry_handler(pb.ipc_shm_entry, ipc_shm_handler()),
'IPCNS_SEM' : entry_handler(pb.ipc_sem_entry, ipc_sem_set_handler()),
'IPCNS_MSG' : entry_handler(pb.ipc_msg_entry, ipc_msg_queue_handler()),
'NETNS' : entry_handler(pb.netns_entry),
'USERNS' : entry_handler(pb.userns_entry),
'SECCOMP' : entry_handler(pb.seccomp_entry),
'AUTOFS' : entry_handler(pb.autofs_entry),
'FILES' : entry_handler(pb.file_entry),
'CPUINFO' : entry_handler(pb.cpuinfo_entry),
}
'INVENTORY': entry_handler(pb.inventory_entry),
'CORE': entry_handler(pb.core_entry),
'IDS': entry_handler(pb.task_kobj_ids_entry),
'CREDS': entry_handler(pb.creds_entry),
'UTSNS': entry_handler(pb.utsns_entry),
'IPC_VAR': entry_handler(pb.ipc_var_entry),
'FS': entry_handler(pb.fs_entry),
'GHOST_FILE': ghost_file_handler(),
'MM': entry_handler(pb.mm_entry),
'CGROUP': entry_handler(pb.cgroup_entry),
'TCP_STREAM': entry_handler(pb.tcp_stream_entry,
tcp_stream_extra_handler()),
'STATS': entry_handler(pb.stats_entry),
'PAGEMAP': pagemap_handler(), # Special one
'PSTREE': entry_handler(pb.pstree_entry),
'REG_FILES': entry_handler(pb.reg_file_entry),
'NS_FILES': entry_handler(pb.ns_file_entry),
'EVENTFD_FILE': entry_handler(pb.eventfd_file_entry),
'EVENTPOLL_FILE': entry_handler(pb.eventpoll_file_entry),
'EVENTPOLL_TFD': entry_handler(pb.eventpoll_tfd_entry),
'SIGNALFD': entry_handler(pb.signalfd_entry),
'TIMERFD': entry_handler(pb.timerfd_entry),
'INOTIFY_FILE': entry_handler(pb.inotify_file_entry),
'INOTIFY_WD': entry_handler(pb.inotify_wd_entry),
'FANOTIFY_FILE': entry_handler(pb.fanotify_file_entry),
'FANOTIFY_MARK': entry_handler(pb.fanotify_mark_entry),
'VMAS': entry_handler(pb.vma_entry),
'PIPES': entry_handler(pb.pipe_entry),
'FIFO': entry_handler(pb.fifo_entry),
'SIGACT': entry_handler(pb.sa_entry),
'NETLINK_SK': entry_handler(pb.netlink_sk_entry),
'REMAP_FPATH': entry_handler(pb.remap_file_path_entry),
'MNTS': entry_handler(pb.mnt_entry),
'TTY_FILES': entry_handler(pb.tty_file_entry),
'TTY_INFO': entry_handler(pb.tty_info_entry),
'TTY_DATA': entry_handler(pb.tty_data_entry),
'RLIMIT': entry_handler(pb.rlimit_entry),
'TUNFILE': entry_handler(pb.tunfile_entry),
'EXT_FILES': entry_handler(pb.ext_file_entry),
'IRMAP_CACHE': entry_handler(pb.irmap_cache_entry),
'FILE_LOCKS': entry_handler(pb.file_lock_entry),
'FDINFO': entry_handler(pb.fdinfo_entry),
'UNIXSK': entry_handler(pb.unix_sk_entry),
'INETSK': entry_handler(pb.inet_sk_entry),
'PACKETSK': entry_handler(pb.packet_sock_entry),
'ITIMERS': entry_handler(pb.itimer_entry),
'POSIX_TIMERS': entry_handler(pb.posix_timer_entry),
'NETDEV': entry_handler(pb.net_device_entry),
'PIPES_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()),
'IPCNS_SHM': entry_handler(pb.ipc_shm_entry, ipc_shm_handler()),
'IPCNS_SEM': entry_handler(pb.ipc_sem_entry, ipc_sem_set_handler()),
'IPCNS_MSG': entry_handler(pb.ipc_msg_entry, ipc_msg_queue_handler()),
'NETNS': entry_handler(pb.netns_entry),
'USERNS': entry_handler(pb.userns_entry),
'SECCOMP': entry_handler(pb.seccomp_entry),
'AUTOFS': entry_handler(pb.autofs_entry),
'FILES': entry_handler(pb.file_entry),
'CPUINFO': entry_handler(pb.cpuinfo_entry),
}
def __rhandler(f):
# Images v1.1 NOTE: First read "first" magic.
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))
try:
@ -528,7 +544,8 @@ def __rhandler(f):
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).
Takes a file-like object to read criu image from.
@ -543,6 +560,7 @@ def load(f, pretty = False, no_payload = False):
return image
def info(f):
res = {}
@ -553,13 +571,15 @@ def info(f):
return res
def loads(s, pretty = False):
def loads(s, pretty=False):
"""
Same as load(), but takes a string.
"""
f = io.BytesIO(s)
return load(f, pretty)
def dump(img, f):
"""
Convert criu image from dict(json) format to binary.
@ -586,6 +606,7 @@ def dump(img, f):
handler.dump(img['entries'], f)
def dumps(img):
"""
Same as dump(), but takes only an image and returns

View File

@ -29,47 +29,50 @@ if "encodebytes" not in dir(base64):
# enums to string value too. (i.e. "march : x86_64" is better then
# "march : 1").
_basic_cast = {
FD.TYPE_FIXED64 : int,
FD.TYPE_FIXED32 : int,
FD.TYPE_SFIXED64 : int,
FD.TYPE_SFIXED32 : int,
FD.TYPE_INT64 : int,
FD.TYPE_UINT64 : int,
FD.TYPE_SINT64 : int,
FD.TYPE_INT32 : int,
FD.TYPE_UINT32 : int,
FD.TYPE_SINT32 : int,
FD.TYPE_BOOL : bool,
FD.TYPE_STRING : str
FD.TYPE_FIXED64: int,
FD.TYPE_FIXED32: int,
FD.TYPE_SFIXED64: int,
FD.TYPE_SFIXED32: int,
FD.TYPE_INT64: int,
FD.TYPE_UINT64: int,
FD.TYPE_SINT64: int,
FD.TYPE_INT32: int,
FD.TYPE_UINT32: int,
FD.TYPE_SINT32: int,
FD.TYPE_BOOL: bool,
FD.TYPE_STRING: str
}
def _marked_as_hex(field):
return field.GetOptions().Extensions[opts_pb2.criu].hex
def _marked_as_ip(field):
return field.GetOptions().Extensions[opts_pb2.criu].ipadd
def _marked_as_flags(field):
return field.GetOptions().Extensions[opts_pb2.criu].flags
def _marked_as_dev(field):
return field.GetOptions().Extensions[opts_pb2.criu].dev
def _marked_as_odev(field):
return field.GetOptions().Extensions[opts_pb2.criu].odev
def _marked_as_dict(field):
return field.GetOptions().Extensions[opts_pb2.criu].dict
def _custom_conv(field):
return field.GetOptions().Extensions[opts_pb2.criu].conv
mmap_prot_map = [
('PROT_READ', 0x1),
('PROT_WRITE', 0x2),
@ -90,17 +93,14 @@ mmap_status_map = [
('VMA_AREA_VSYSCALL', 1 << 2),
('VMA_AREA_VDSO', 1 << 3),
('VMA_AREA_HEAP', 1 << 5),
('VMA_FILE_PRIVATE', 1 << 6),
('VMA_FILE_SHARED', 1 << 7),
('VMA_ANON_SHARED', 1 << 8),
('VMA_ANON_PRIVATE', 1 << 9),
('VMA_AREA_SYSVIPC', 1 << 10),
('VMA_AREA_SOCKET', 1 << 11),
('VMA_AREA_VVAR', 1 << 12),
('VMA_AREA_AIORING', 1 << 13),
('VMA_UNSUPP', 1 << 31),
]
@ -119,29 +119,38 @@ pmap_flags_map = [
]
flags_maps = {
'mmap.prot' : mmap_prot_map,
'mmap.flags' : mmap_flags_map,
'mmap.status' : mmap_status_map,
'rfile.flags' : rfile_flags_map,
'pmap.flags' : pmap_flags_map,
'mmap.prot': mmap_prot_map,
'mmap.flags': mmap_flags_map,
'mmap.status': mmap_status_map,
'rfile.flags': rfile_flags_map,
'pmap.flags': pmap_flags_map,
}
gen_maps = {
'task_state' : { 1: 'Alive', 3: 'Zombie', 6: 'Stopped' },
'task_state': {
1: 'Alive',
3: 'Zombie',
6: 'Stopped'
},
}
sk_maps = {
'family' : { 1: 'UNIX',
'family': {
1: 'UNIX',
2: 'INET',
10: 'INET6',
16: 'NETLINK',
17: 'PACKET' },
'type' : { 1: 'STREAM',
17: 'PACKET'
},
'type': {
1: 'STREAM',
2: 'DGRAM',
3: 'RAW',
5: 'SEQPACKET',
10: 'PACKET' },
'state' : { 1: 'ESTABLISHED',
10: 'PACKET'
},
'state': {
1: 'ESTABLISHED',
2: 'SYN_SENT',
3: 'SYN_RECV',
4: 'FIN_WAIT1',
@ -150,21 +159,33 @@ sk_maps = {
7: 'CLOSE',
8: 'CLOSE_WAIT',
9: 'LAST_ACK',
10: 'LISTEN' },
'proto' : { 0: 'IP',
10: 'LISTEN'
},
'proto': {
0: 'IP',
6: 'TCP',
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()) }
sk_rmaps = { k: {v2:k2 for k2,v2 in list(v.items())} for k,v in list(sk_maps.items()) }
gen_rmaps = {
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 = {
'gen' : ( gen_maps, gen_rmaps ),
'sk' : ( sk_maps, sk_rmaps ),
'gen': (gen_maps, gen_rmaps),
'sk': (sk_maps, sk_rmaps),
}
def map_flags(value, flags_map):
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])
@ -172,20 +193,28 @@ def map_flags(value, flags_map):
bs.append("0x%x" % value)
return " | ".join(bs)
def unmap_flags(value, flags_map):
if value == '':
return 0
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
def decode_dev(field, value):
if _marked_as_odev(field):
return "%d:%d" % (os.major(value), os.minor(value))
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):
dev = [int(x) for x in value.split(':')]
@ -194,18 +223,26 @@ def encode_dev(field, value):
else:
return dev[0] << kern_minorbits | dev[1]
def encode_base64(value):
return base64.encodebytes(value)
def decode_base64(value):
return base64.decodebytes(value)
def encode_unix(value):
return quopri.encodestring(value)
def decode_unix(value):
return quopri.decodestring(value)
encode = { 'unix_name': encode_unix }
decode = { 'unix_name': decode_unix }
encode = {'unix_name': encode_unix}
decode = {'unix_name': decode_unix}
def get_bytes_enc(field):
c = _custom_conv(field)
@ -214,6 +251,7 @@ def get_bytes_enc(field):
else:
return encode_base64
def get_bytes_dec(field):
c = _custom_conv(field)
if c:
@ -221,6 +259,7 @@ def get_bytes_dec(field):
else:
return decode_base64
def is_string(value):
# Python 3 compatibility
if "basestring" in __builtins__:
@ -229,7 +268,8 @@ def is_string(value):
string_types = (str, bytes)
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:
is_hex = _marked_as_hex(field)
@ -254,7 +294,7 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
if flags:
try:
flags_map = flags_maps[flags]
except:
except Exception:
return "0x%x" % value # flags are better seen as hex anyway
else:
return map_flags(value, flags_map)
@ -265,9 +305,11 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
return cast(value)
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):
"""
Convert protobuf msg to dictionary.
Takes a protobuf message and returns a dict.
@ -297,6 +339,7 @@ def pb2dict(pb, pretty = False, is_hex = False):
d[field.name] = d_val
return d
def _dict2pb_cast(field, value):
# Not considering TYPE_MESSAGE here, as repeated
# and non-repeated messages need special treatment
@ -315,7 +358,7 @@ def _dict2pb_cast(field, value):
if flags:
try:
flags_map = flags_maps[flags]
except:
except Exception:
pass # Try to use plain string cast
else:
return unmap_flags(value, flags_map)
@ -323,7 +366,7 @@ def _dict2pb_cast(field, value):
dct = _marked_as_dict(field)
if dct:
ret = dict_maps[dct][1][field.name].get(value, None)
if ret == None:
if ret is None:
ret = cast(value, 0)
return ret
@ -333,7 +376,9 @@ def _dict2pb_cast(field, value):
else:
return cast(value)
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):
"""
@ -357,7 +402,8 @@ def dict2pb(d, pb):
pb_val.append(socket.htonl((ival >> (32 * 1)) & 0xFFFFFFFF))
pb_val.append(socket.htonl((ival >> (32 * 0)) & 0xFFFFFFFF))
else:
raise Exception("Unknown IP address version %d" % val.version)
raise Exception("Unknown IP address version %d" %
val.version)
continue
for v in value:

View File

@ -1,12 +1,11 @@
from distutils.core import setup
setup(name = "crit",
version = "0.0.1",
description = "CRiu Image Tool",
author = "CRIU team",
author_email = "criu@openvz.org",
url = "https://github.com/checkpoint-restore/criu",
package_dir = {'pycriu': 'lib/py'},
packages = ["pycriu", "pycriu.images"],
scripts = ["crit/crit"]
)
setup(name="crit",
version="0.0.1",
description="CRiu Image Tool",
author="CRIU team",
author_email="criu@openvz.org",
url="https://github.com/checkpoint-restore/criu",
package_dir={'pycriu': 'lib/py'},
packages=["pycriu", "pycriu.images"],
scripts=["crit/crit"])

View File

@ -1,6 +1,7 @@
#!/bin/env python2
import sys
# This program parses criu magic.h file and produces
# magic.py with all *_MAGIC constants except RAW and V1.
def main(argv):
@ -43,7 +44,7 @@ def main(argv):
out.write('#Autogenerated. Do not edit!\n')
out.write('by_name = {}\n')
out.write('by_val = {}\n')
for k,v in list(magic.items()):
for k, v in list(magic.items()):
# We don't need RAW or V1 magic, because
# they can't be used to identify images.
if v == '0x0' or v == '1' or k == '0x0' or v == '1':
@ -52,10 +53,11 @@ def main(argv):
# Just cutting _MAGIC suffix
k = k[:-6]
v = int(v, 16)
out.write("by_name['"+ k +"'] = "+ str(v) +"\n")
out.write("by_val["+ str(v) +"] = '"+ k +"'\n")
out.write("by_name['" + k + "'] = " + str(v) + "\n")
out.write("by_val[" + str(v) + "] = '" + k + "'\n")
f.close()
out.close()
if __name__ == "__main__":
main(sys.argv)

View File

@ -13,17 +13,17 @@ sport = os.getenv("TCP_SPORT", "12345")
dport = os.getenv("TCP_DPORT", "54321")
print(sys.argv[1])
args = [sys.argv[1],
"--addr", src, "--port", sport, "--seq", "555",
"--next",
"--addr", dst, "--port", dport, "--seq", "666",
"--reverse", "--", "./tcp-test.py"]
args = [
sys.argv[1], "--addr", src, "--port", sport, "--seq", "555", "--next",
"--addr", dst, "--port", dport, "--seq", "666", "--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)
p1.stdout.read(5)
p2.stdout.read(5)
@ -42,7 +42,7 @@ str2 = m.hexdigest()
if str2 != eval(s):
print("FAIL", repr(str2), repr(s))
sys.exit(5);
sys.exit(5)
s = p1.stdout.read()
m = hashlib.md5()
@ -52,7 +52,7 @@ str1 = m.hexdigest()
s = p2.stdout.read()
if str1 != eval(s):
print("FAIL", repr(str1), s)
sys.exit(5);
sys.exit(5)
if p1.wait():
sys.exit(1)

View File

@ -25,7 +25,8 @@ for act in open(af):
if act[2] == 'EMPTY':
errors.append('Action %s misses CRTOOLS_INIT_PID' % act[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]])

View File

@ -6,11 +6,13 @@ import sys
import os
import subprocess
find = subprocess.Popen(['find', 'test/dump/', '-size', '+0', '-name', '*.img'],
stdout = subprocess.PIPE)
find = subprocess.Popen(
['find', 'test/dump/', '-size', '+0', '-name', '*.img'],
stdout=subprocess.PIPE)
test_pass = True
def recode_and_check(imgf, o_img, pretty):
try:
pb = pycriu.images.loads(o_img, pretty)

View File

@ -8,7 +8,8 @@ import time
import sys
import subprocess
criu_bin='../../criu/criu'
criu_bin = '../../criu/criu'
def mix(nr_tasks, nr_pipes):
# Returned is the list of combinations.
@ -26,7 +27,7 @@ def mix(nr_tasks, nr_pipes):
# newbie.
pipes_mix = pipe_mix
for t in range(1, nr_pipes):
pipes_mix = [ o + n for o in pipes_mix for n in pipe_mix ]
pipes_mix = [o + n for o in pipes_mix for n in pipe_mix]
return pipes_mix
@ -114,6 +115,7 @@ def check_pipe(kids, fds, comb, inos):
return res + 'end(%d)' % e
return None
def check_pipes(kids, pipes, comb):
# Kids contain pids
# Pipes contain pipe FDs
@ -198,14 +200,20 @@ def cr_test(pid):
img_dir = 'pimg_%d' % pid
try:
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:
print('`- dump fail')
return False
try:
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:
print('`- restore fail')
return False
@ -254,8 +262,8 @@ def run(comb, opts):
p = argparse.ArgumentParser("CRIU test suite")
p.add_argument("--tasks", help = "Number of tasks", default = '2')
p.add_argument("--pipes", help = "Number of pipes", default = '2')
p.add_argument("--tasks", help="Number of tasks", default='2')
p.add_argument("--pipes", help="Number of pipes", default='2')
opts = p.parse_args()
opts.tasks = int(opts.tasks)
opts.pipes = int(opts.pipes)

View File

@ -9,7 +9,7 @@ import signal
import fcntl
import stat
criu_bin='../../criu/criu'
criu_bin = '../../criu/criu'
sk_type_s = {
socket.SOCK_STREAM: "S",
@ -25,12 +25,14 @@ sk_type_s = {
# - do() method, that actually does what's required
# - show() method to return the string description of what's done
def mk_socket(st, typ):
st.sk_id += 1
sk = sock(st.sk_id, typ)
st.add_socket(sk)
return sk
class act_socket:
def __init__(self, typ):
self.typ = typ
@ -174,12 +176,14 @@ class act_sendmsg:
sk.sendto(msgv, sock.real_name_for(self.to_id))
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
def msgval(msgid, pref = ''):
def msgval(msgid, pref=''):
return '%sMSG%d' % (pref, msgid)
#
# Description of a socket
#
@ -246,9 +250,9 @@ class sock:
if lmsg[0] == self.sk_id:
want_msg = False
if want_msg:
return [ act_sendmsg(self.sk_id, to.sk_id) ]
return [act_sendmsg(self.sk_id, to.sk_id)]
else:
return [ ]
return []
def get_stream_actions(self, st):
act_list = []
@ -378,7 +382,7 @@ class state:
def del_socket(self, sk):
self.sockets.remove(sk)
def get_socket(self, sk_id, can_be_null = False):
def get_socket(self, sk_id, can_be_null=False):
for sk in self.sockets:
if sk.sk_id == sk_id:
return sk
@ -425,6 +429,7 @@ def set_nonblock(sk):
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
CHK_FAIL_UNKNOWN = 10
CHK_FAIL_SOCKET = 11
CHK_FAIL_STAT = 12
@ -455,6 +460,7 @@ fail_desc = {
CHK_FAIL_RESTORE: 'Cannot restore',
}
def chk_real_state(st):
# Before enything else -- check that we still have
# all the sockets at hands
@ -485,16 +491,16 @@ def chk_real_state(st):
rsk = st.real_sockets[sk.sk_id]
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):
print("FAIL: Socket %d listen %d, expected %d"
% (sk.sk_id, r_listen, sk.listen and 1 or 0))
print("FAIL: Socket %d listen %d, expected %d" %
(sk.sk_id, r_listen, sk.listen and 1 or 0))
return CHK_FAIL_LISTEN
if sk.name:
r_name = rsk.getsockname()
w_name = sock.real_name_for(sk.name)
if r_name != w_name:
print('FAIL: Socket %d name mismatch [%s], want [%s]'
% (sk.sk_id, r_name, w_name))
print('FAIL: Socket %d name mismatch [%s], want [%s]' %
(sk.sk_id, r_name, w_name))
return CHK_FAIL_NAME
# Second -- check (accept) pending connections
@ -513,7 +519,8 @@ def chk_real_state(st):
try:
acc.do(st)
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
print(' `- did %s' % acc.show())
@ -536,13 +543,13 @@ def chk_real_state(st):
w_msg = act_sendmsg.msgval(msg[1])
if r_msg != w_msg:
print('FAIL: Message misorder: %s want %s (from %d)'
%(r_msg, w_msg, msg[0]))
print('FAIL: Message misorder: %s want %s (from %d)' %
(r_msg, w_msg, msg[0]))
return CHK_FAIL_RECV_MIX
# TODO -- check sender
print(' `- recvd %d.%d msg %s -> %d'
% (msg[0], msg[1], m_from, sk.sk_id))
print(' `- recvd %d.%d msg %s -> %d' %
(msg[0], msg[1], m_from, sk.sk_id))
# Finally, after all sockets are visible and all inqueues are
# drained -- check the sockets connectivity
@ -557,7 +564,8 @@ def chk_real_state(st):
rsk = st.real_sockets[sk.sk_id]
psk = st.real_sockets[sk.peer]
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:
rsk.send(msgv)
@ -572,8 +580,8 @@ def chk_real_state(st):
# the hard way -- also check for the message being
# delivered for real
if rmsg != msgv:
print('FAIL: Connectivity %d -> %d not verified'
% (sk.sk_id, sk.peer))
print('FAIL: Connectivity %d -> %d not verified' %
(sk.sk_id, sk.peer))
return CHK_FAIL_CONNECT2
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()
try:
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:
print("Dump failed")
os.kill(pid, signal.SIGKILL)
@ -618,7 +629,10 @@ def chk_state(st, opts):
print("`- restore")
try:
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:
print("Restore failed")
return CHK_FAIL_RESTORE
@ -673,7 +687,7 @@ def run_state(st, opts):
sys.exit(ret)
def proceed(st, seen, failed, opts, depth = 0):
def proceed(st, seen, failed, opts, depth=0):
desc = st.describe()
if not desc:
pass
@ -718,13 +732,17 @@ def proceed(st, seen, failed, opts, depth = 0):
p = argparse.ArgumentParser("CRIU test suite")
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("--dgram", help = "Use SOCK_DGRAM 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("--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("--depth", help="Depth of generated tree", default='8')
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("--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("--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')
opts = p.parse_args()
opts.depth = int(opts.depth)
@ -751,4 +769,5 @@ if len(failed) == 0:
else:
print('FAIL %d/%d' % (len(failed), len(seen)))
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])))

View File

@ -4,7 +4,6 @@ import os
import pty
import termios
ctl = False

View File

@ -5,13 +5,19 @@ import os, sys, time, signal, pty
master, slave = pty.openpty()
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)
ttyid = "tty[%x:%x]" % (st.st_rdev, st.st_dev)
os.close(slave)
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:
sys.exit(ret)
p.wait()
@ -21,7 +27,10 @@ os.close(master)
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:
sys.exit(ret)
os.close(slave)

View File

@ -1,6 +1,7 @@
import os
import tempfile, random
def mount(src, dst, shared, private, slave):
cmd = "mount"
if shared:
@ -19,13 +20,17 @@ def mount(src, dst, shared, private, slave):
if ret:
print("failed")
root = tempfile.mkdtemp(prefix = "root.mount", dir = "/tmp")
root = tempfile.mkdtemp(prefix="root.mount", dir="/tmp")
mount(None, root, 1, 0, 0)
mounts = [root]
for i in range(10):
dstdir = random.choice(mounts)
dst = tempfile.mkdtemp(prefix = "mount", dir = dstdir)
dst = tempfile.mkdtemp(prefix="mount", dir=dstdir)
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)

View File

@ -99,7 +99,9 @@ def test_broken_configuration_file():
def search_in_log_file(log, message):
with open(os.path.join(args['dir'], log)) as f:
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)
@ -175,8 +177,11 @@ def test_rpc_with_configuration_file_overwriting_rpc():
check_results(resp, log)
parser = argparse.ArgumentParser(description="Test config files using CRIU RPC")
parser.add_argument('dir', type = str, help = "Directory where CRIU images should be placed")
parser = argparse.ArgumentParser(
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())

View File

@ -6,11 +6,14 @@ import rpc_pb2 as rpc
import argparse
parser = argparse.ArgumentParser(description="Test errno reported by CRIU RPC")
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('socket', type=str, help="CRIU service socket")
parser.add_argument('dir',
type=str,
help="Directory where CRIU images should be placed")
args = vars(parser.parse_args())
# Prepare dir for images
class test:
def __init__(self):
@ -73,7 +76,9 @@ class test:
print('Success')
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
req = self.get_base_req()
@ -131,5 +136,6 @@ class test:
self.bad_options()
self.bad_request()
t = test()
t.run()

View File

@ -5,8 +5,10 @@ import rpc_pb2 as rpc
import argparse
parser = argparse.ArgumentParser(description="Test page-server using CRIU RPC")
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('socket', type=str, help="CRIU service socket")
parser.add_argument('dir',
type=str,
help="Directory where CRIU images should be placed")
args = vars(parser.parse_args())
@ -38,16 +40,16 @@ else:
os.kill(resp.ps.pid, 0)
except OSError as err:
if err.errno == errno.ESRCH:
print('No process with page-server pid %d' %(resp.ps.pid))
print('No process with page-server pid %d' % (resp.ps.pid))
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)
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:
print('Failed to start page-server')
sys.exit(1)
# Perform self-dump
print('Dumping myself using page-server')
req.type = rpc.DUMP

View File

@ -4,9 +4,12 @@ import socket, os, sys
import rpc_pb2 as rpc
import argparse
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('dir', type = str, help = "Directory where CRIU images could be found")
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('dir',
type=str,
help="Directory where CRIU images could be found")
args = vars(parser.parse_args())
@ -42,4 +45,4 @@ else:
else:
print('Restore fail')
sys.exit(-1)
print("PID of the restored program is %d\n" %(resp.restore.pid))
print("PID of the restored program is %d\n" % (resp.restore.pid))

View File

@ -4,9 +4,12 @@ import socket, os, sys
import rpc_pb2 as rpc
import argparse
parser = argparse.ArgumentParser(description="Test dump/restore using CRIU RPC")
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 = argparse.ArgumentParser(
description="Test dump/restore using CRIU RPC")
parser.add_argument('socket', type=str, help="CRIU service socket")
parser.add_argument('dir',
type=str,
help="Directory where CRIU images should be placed")
args = vars(parser.parse_args())

View File

@ -6,15 +6,17 @@ cr_bin = "../../../criu/criu"
os.chdir(os.getcwd())
def create_pty():
(fd1, fd2) = pty.openpty()
return (os.fdopen(fd1, "w+"), os.fdopen(fd2, "w+"))
if not os.access("work", os.X_OK):
os.mkdir("work", 0755)
open("running", "w").close()
m,s = create_pty()
m, s = create_pty()
p = os.pipe()
pr = os.fdopen(p[0], "r")
pw = os.fdopen(p[1], "w")
@ -46,14 +48,15 @@ if ret != 0:
os.wait()
os.unlink("running")
m,s = create_pty()
m, s = create_pty()
cpid = os.fork()
if cpid == 0:
os.setsid()
fcntl.ioctl(m.fileno(), termios.TIOCSCTTY, 1)
cmd = [cr_bin, "restore", "-j", "-D", "work", "-v"]
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:
sys.exit(1)
sys.exit(0)

File diff suppressed because it is too large Load Diff