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:
parent
5ff4fcb753
commit
5aa72e7237
@ -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:
|
||||
|
@ -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;
|
||||
|
158
lib/py/cli.py
158
lib/py/cli.py
@ -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()
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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"])
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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]])
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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])))
|
||||
|
@ -4,7 +4,6 @@ import os
|
||||
import pty
|
||||
import termios
|
||||
|
||||
|
||||
ctl = False
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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())
|
||||
|
||||
|
@ -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)
|
||||
|
561
test/zdtm.py
561
test/zdtm.py
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user