[CRIU] [PATCH 4/9] pycriu: add python package
Pavel Emelyanov
xemul at parallels.com
Wed Oct 8 09:04:45 PDT 2014
> --- /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?
> 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?
> +
> +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