[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