[CRIU] [PATCH 4/9] pycriu: add python package

Ruslan Kuprieiev kupruser at gmail.com
Wed Oct 8 09:13:03 PDT 2014


On 08.10.2014 19:04, Pavel Emelyanov wrote:
>> --- /dev/null
>> +++ b/pycriu/images/Makefile
>> @@ -0,0 +1,17 @@
>> +all: protobuf magic.py
>> +
>> +.PHONY: all protobuf clean
>> +
>> +# We don't need rpc_pb2.py here, as it is not related to the
>> +# images.
>> +# Unfortunately, we can't drop ugly _pb2 suffixes here, because
>> +# some _pb2 files depend on others _pb2 files.
>> +protobuf:
>> +	$(Q) cp $(SRC_DIR)/protobuf/*_pb2.py ./ ; rm rpc_pb2.py
> Wow... Cyrill, can we do it in a nicer way?
>
>> +
>> +magic.py: $(SRC_DIR)/scripts/magic-gen.py $(SRC_DIR)/include/magic.h
>> +	$(E) "  GEN  " $@
>> +	$(Q) python $^ $@
>> +
>> +clean:
>> +	$(Q) $(RM) ./*_pb2.py ./*.pyc magic.py
>> diff --git a/pycriu/images/__init__.py b/pycriu/images/__init__.py
>> new file mode 100644
>> index 0000000..6ad6d6b
>> --- /dev/null
>> +++ b/pycriu/images/__init__.py
>> @@ -0,0 +1,53 @@
>> +from images import *
>> +
>> +import stats_pb2
>> +import timer_pb2
>> +import ipc_sem_pb2
>> +import core_pb2
>> +import core_x86_pb2
>> +import remap_file_path_pb2
>> +import fsnotify_pb2
>> +import inventory_pb2
>> +import tcp_stream_pb2
>> +import mnt_pb2
>> +import packet_sock_pb2
>> +import pipe_data_pb2
>> +import ipc_var_pb2
>> +import sa_pb2
>> +import tun_pb2
>> +import fown_pb2
>> +import tty_pb2
>> +import rlimit_pb2
>> +import ipc_shm_pb2
>> +import file_lock_pb2
>> +import sk_unix_pb2
>> +import sk_packet_pb2
>> +import pagemap_pb2
>> +import pipe_pb2
>> +import pstree_pb2
>> +import sk_opts_pb2
>> +import siginfo_pb2
>> +import cgroup_pb2
>> +import fh_pb2
>> +import ipc_msg_pb2
>> +import mm_pb2
>> +import netdev_pb2
>> +import timerfd_pb2
>> +import ns_pb2
>> +import fs_pb2
>> +import ext_file_pb2
>> +import signalfd_pb2
>> +import ipc_desc_pb2
>> +import fdinfo_pb2
>> +import fifo_pb2
>> +import eventpoll_pb2
>> +import regfile_pb2
>> +import core_arm_pb2
>> +import sk_netlink_pb2
>> +import sk_inet_pb2
>> +import utsns_pb2
>> +import core_aarch64_pb2
>> +import eventfd_pb2
>> +import creds_pb2
>> +import vma_pb2
>> +import ghost_file_pb2
> Can this file be generated like the magic.py is?

Yes, it can be generated in a nicer way. I guess it will be resolved 
right after my makefile ugliness.

>> diff --git a/pycriu/images/images.py b/pycriu/images/images.py
>> new file mode 100644
>> index 0000000..e45d432
>> --- /dev/null
>> +++ b/pycriu/images/images.py
>> @@ -0,0 +1,259 @@
>> +#!/bin/env python
>> +import io
>> +import google
>> +import struct
>> +import os
>> +import sys
>> +
>> +from magic import *
>> +
>> +from stats_pb2 import *
>> +from timer_pb2 import *
>> +from ipc_sem_pb2 import *
>> +from core_pb2 import *
>> +from core_x86_pb2 import *
>> +from remap_file_path_pb2 import *
>> +from fsnotify_pb2 import *
>> +from inventory_pb2 import *
>> +from tcp_stream_pb2 import *
>> +from mnt_pb2 import *
>> +from packet_sock_pb2 import *
>> +from pipe_data_pb2 import *
>> +from ipc_var_pb2 import *
>> +from sa_pb2 import *
>> +from tun_pb2 import *
>> +from fown_pb2 import *
>> +from tty_pb2 import *
>> +from rlimit_pb2 import *
>> +from ipc_shm_pb2 import *
>> +from file_lock_pb2 import *
>> +from sk_unix_pb2 import *
>> +from sk_packet_pb2 import *
>> +from pagemap_pb2 import *
>> +from pipe_pb2 import *
>> +from pstree_pb2 import *
>> +from sk_opts_pb2 import *
>> +from siginfo_pb2 import *
>> +from cgroup_pb2 import *
>> +from fh_pb2 import *
>> +from ipc_msg_pb2 import *
>> +from mm_pb2 import *
>> +from netdev_pb2 import *
>> +from timerfd_pb2 import *
>> +from ns_pb2 import *
>> +from fs_pb2 import *
>> +from ext_file_pb2 import *
>> +from signalfd_pb2 import *
>> +from ipc_desc_pb2 import *
>> +from fdinfo_pb2 import *
>> +from fifo_pb2 import *
>> +from eventpoll_pb2 import *
>> +from regfile_pb2 import *
>> +from core_arm_pb2 import *
>> +from sk_netlink_pb2 import *
>> +from sk_inet_pb2 import *
>> +from utsns_pb2 import *
>> +from core_aarch64_pb2 import *
>> +from eventfd_pb2 import *
>> +from creds_pb2 import *
>> +from vma_pb2 import *
>> +from ghost_file_pb2 import *
> This part is almost the same as the __init__.py is. Can it be merged?

Yes, i'll see what i can do about it.

>> +
>> +class _cr_desc:
>> +	def __init__(self, magic, head, body='', single=False):
>> +		self.magic_name = magic
>> +		self.magic = eval(magic+"_MAGIC")
>> +		self.head_name = head
>> +		self.head = eval(head)
>> +		if single:
>> +			self.body_name = ''
>> +			self.body = lambda : None
>> +		else:
>> +			if body == '':
>> +				body = head
>> +			self.body_name = body
>> +			self.body = eval(body)
>> +
>> +class criu_image_descs:
>> +	def __init__(self):
>> +		self.descs = [
>> +	_cr_desc('INVENTORY',	'inventory_entry',	single=True),
>> +	_cr_desc('CORE',	'core_entry',		single=True),
>> +	_cr_desc('IDS',		'task_kobj_ids_entry',	single=True),
>> +	_cr_desc('CREDS',	'creds_entry',		single=True),
>> +	_cr_desc('UTSNS',	'utsns_entry',		single=True),
>> +	_cr_desc('IPC_VAR',	'ipc_var_entry',	single=True),
>> +	_cr_desc('FS',		'fs_entry',		single=True),
>> +	_cr_desc('GHOST_FILE',	'ghost_file_entry',	single=True),
>> +	_cr_desc('MM',		'mm_entry',		single=True),
>> +	_cr_desc('CGROUP',	'cgroup_entry',		single=True),
>> +	_cr_desc('TCP_STREAM',	'tcp_stream_entry',	single=True),
>> +	_cr_desc('STATS',	'stats_entry',		single=True),
>> +
>> +	_cr_desc('PAGEMAP',	'pagemap_head',		body='pagemap_entry'),
>> +
>> +	_cr_desc('PSTREE',		'pstree_entry'),
>> +	_cr_desc('REG_FILES',		'reg_file_entry'),
>> +	_cr_desc('NS_FILES',		'ns_file_entry'),
>> +	_cr_desc('EVENTFD_FILE',	'eventfd_file_entry'),
>> +	_cr_desc('EVENTPOLL_FILE',	'eventpoll_file_entry'),
>> +	_cr_desc('EVENTPOLL_TFD',	'eventpoll_tfd_entry'),
>> +	_cr_desc('SIGNALFD',		'signalfd_entry'),
>> +	_cr_desc('TIMERFD',		'timerfd_entry'),
>> +	_cr_desc('INOTIFY_FILE',	'inotify_file_entry'),
>> +	_cr_desc('INOTIFY_WD',		'inotify_wd_entry'),
>> +	_cr_desc('FANOTIFY_FILE',	'fanotify_file_entry'),
>> +	_cr_desc('FANOTIFY_MARK',	'fanotify_mark_entry'),
>> +	_cr_desc('VMAS',		'vma_entry'),
>> +	_cr_desc('PIPES',		'pipe_entry'),
>> +	_cr_desc('FIFO',		'fifo_entry'),
>> +	_cr_desc('SIGACT',		'sa_entry'),
>> +	_cr_desc('NETLINK_SK',		'netlink_sk_entry'),
>> +	_cr_desc('REMAP_FPATH',		'remap_file_path_entry'),
>> +	_cr_desc('MNTS',		'mnt_entry'),
>> +	_cr_desc('TTY_FILES',		'tty_file_entry'),
>> +	_cr_desc('TTY_INFO',		'tty_info_entry'),
>> +	_cr_desc('RLIMIT',		'rlimit_entry'),
>> +	_cr_desc('TUNFILE',		'tunfile_entry'),
>> +	_cr_desc('EXT_FILES',		'ext_file_entry'),
>> +	_cr_desc('IRMAP_CACHE',		'irmap_cache_entry'),
>> +	_cr_desc('FILE_LOCKS',		'file_lock_entry'),
>> +	_cr_desc('FDINFO',		'fdinfo_entry'),
>> +	_cr_desc('UNIXSK',		'unix_sk_entry'),
>> +	_cr_desc('INETSK',		'inet_sk_entry'),
>> +	_cr_desc('PACKETSK', 		'packet_sock_entry'),
>> +	_cr_desc('ITIMERS',		'itimer_entry'),
>> +	_cr_desc('POSIX_TIMERS',	'posix_timer_entry'),
>> +	_cr_desc('NETDEV',		'net_device_entry'),
>> +	_cr_desc('PIPES_DATA',		'pipe_data_entry'),
>> +	_cr_desc('FIFO_DATA',		'pipe_data_entry'),
>> +	_cr_desc('SK_QUEUES',		'sk_packet_entry'),
>> +	_cr_desc('IPCNS_SHM',		'ipc_shm_entry'),
>> +	_cr_desc('IPCNS_SEM',		'ipc_sem_entry'),
>> +	_cr_desc('IPCNS_MSG',		'ipc_msg_entry')
>> +	]
>> +
>> +	def get(self, magic):
>> +		desc = None
>> +		for d in self.descs:
>> +			if d.magic == magic or d.magic_name == magic:
>> +				desc = d
>> +				break
> Can we store d-s in a dict and just make dict[magic] here?
>
>> +		if desc == None:
>> +			raise Exception("Unknown magic")
>> +		else:
>> +			return desc
>> +
>> +class criu_image:
>> +	def __init__(self):
>> +		self.desc	= None
>> +		self.msgs	= []
>> +		self.orig_type	= None
>> +
>> +	def ParseFromStringIMG(self, s):
>> +		s = io.BytesIO(s)
>> +		magic, = struct.unpack('i', s.read(4))
>> +		magic = "0x{0:x}".format(magic)
>> +
>> +		descs = criu_image_descs()
>> +		try:
>> +			self.desc = descs.get(magic)
>> +		except Exception as e:
>> +			raise e
>> +
>> +		pb = self.desc.head()
>> +		while pb != None:
>> +			buf = s.read(4)
>> +			if buf == '':
>> +				break
>> +			size, = struct.unpack('i', buf)
>> +			pb.ParseFromString(s.read(size))
>> +			self.msgs.append(pb)
>> +			pb = self.desc.body()
>> +
>> +	def ParseFromStringTXT(self, s):
>> +		s = io.BytesIO(s)
>> +		magic = (s.readline())[1:-1]
>> +
>> +		descs = criu_image_descs()
>> +		try:
>> +			self.desc = descs.get(magic)
>> +		except Exception as e:
>> +			raise e
>> +
>> +		pb = self.desc.head()
>> +		while pb != None:
>> +			buf = s.readline()
>> +			if buf == '':
>> +				break
>> +			if buf[0] != '#':
>> +				raise Exception('# expected')
>> +			pb_text = ''
>> +			while True:
>> +				buf = s.readline()
>> +				if buf == '':
>> +					break
>> +				if buf[0] == '#':
>> +					s.seek(-len(buf), 1)
>> +					break
>> +				elif buf[0] == '':
>> +					raise Exception("data expected")
>> +				else:
>> +					pb_text += buf
>> +			google.protobuf.text_format.Merge(pb_text, pb)
>> +			self.msgs.append(pb)
>> +			pb = self.desc.body()
>> +
>> +	def ParseFromString(self, s):
>> +		if s[0] == '#':
>> +			self.orig_type = 'txt'
>> +			self.ParseFromStringTXT(s)
>> +		else:
>> +			self.orig_type = 'img'
>> +			self.ParseFromStringIMG(s)
>> +
>> +	def SerializeToStringIMG(self):
>> +		s = io.BytesIO('')
>> +		s.write(struct.pack('i', int(self.desc.magic, 16)))
>> +
>> +		for pb in self.msgs:
>> +			pb_str = pb.SerializeToString()
>> +			size = len(pb_str)
>> +			s.write(struct.pack('i', size))
>> +			s.write(pb_str)
>> +		s.seek(0)
>> +		return s.read()
>> +
>> +	def SerializeToStringTXT(self, nice=False):
>> +		s = io.BytesIO('')
>> +
>> +		if nice:
>> +			magic = self.desc.magic_name
>> +			indent = 4
>> +		else:
>> +			magic = self.desc.magic
>> +			indent = 0
>> +
>> +		s.write('#'+magic+'\n')
>> +
>> +		index = 0
>> +		for pb in self.msgs:
>> +			if nice:
>> +				if index == 0:
>> +					pb_name = self.desc.head_name
>> +				else:
>> +					pb_name = self.desc.body_name
>> +			else:
>> +				pb_name = ''
>> +
>> +			s.write('#'+str(index)+' '+pb_name+'\n')
>> +			google.protobuf.text_format.PrintMessage(pb, s, indent=indent)
>> +			index += 1
>> +		s.seek(0)
>> +		return s.read()
>> +
>> +	def SerializeToString(self, nice=False):
>> +		if self.orig_type == 'img':
>> +			return self.SerializeToStringTXT(nice=nice)
>> +		else:
>> +			return self.SerializeToStringIMG()
>>



More information about the CRIU mailing list