Drop IVServer.py in favor of ivserver native.
This change adds some extra section to a new vsoc_mem.json definition.
We need this to properly set up guest - or we need to figure out how else to pass it.
Change-Id: Ia27b8eb58b9a54e57f46f787a997e29b17b00119
(cherry picked from commit b519aa6c7895f1f2050b361ea724cd8f8442722e)
diff --git a/ivserver/vsoc_mem.json b/ivserver/vsoc_mem.json
index 2a23d8b..cfaceb5 100644
--- a/ivserver/vsoc_mem.json
+++ b/ivserver/vsoc_mem.json
@@ -1,4 +1,18 @@
{
+ "guest": {
+ "vmm_path": "/usr/bin/qemu-system-x86_64",
+ "kernel_command_line" : [
+ "loop.max_part=7",
+ "console=ttyS0",
+ "androidboot.console=ttyS0",
+ "androidboot.hardware=vsoc",
+ "security=selinux",
+ "androidboot.selinux=permissive",
+ "enforcing=0",
+ "audit=0",
+ "CUTTLEFISH"
+ ]
+ },
"vsoc_shm_layout_descriptor" : {
"comment": "The top level layout descriptor",
"major_version" : 0,
diff --git a/launcher/BUILD b/launcher/BUILD
index d57c02f..08235c2 100644
--- a/launcher/BUILD
+++ b/launcher/BUILD
@@ -3,13 +3,9 @@
py_library(
name = "ivserver_lib",
srcs = [
- "channel.py",
- "clientconnection.py",
"guest_definition.py",
"ivserver.py",
"libvirt_client.py",
- "vmconnection.py",
- "vsocsharedmem.py",
],
srcs_version = "PY2AND3",
)
diff --git a/launcher/channel.py b/launcher/channel.py
deleted file mode 100644
index 8f90f8c..0000000
--- a/launcher/channel.py
+++ /dev/null
@@ -1,72 +0,0 @@
-'''
- Related to the UNIX Domain Socket.
-'''
-
-import fcntl
-import os
-import socket
-import stat
-import struct
-import glog
-
-# From include/uapi/asm-generic/ioctls.h
-# #define FIONBIO 0x5421
-_FIONBIO = 0x5421
-
-
-def start_listener(path):
- uds = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- uds.bind(path)
- uds.listen(5)
- os.chmod(path,
- stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
- stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP |
- stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH)
- glog.info('Socket %s ready.' % path)
- return uds
-
-
-def connect_to_channel(path):
- uds = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- uds.connect(path)
- return uds
-
-
-def handle_new_connection(uds, nonblocking=True):
- sock, _ = uds.accept()
-
- if nonblocking:
- # Set the new socket to non-blocking mode.
- try:
- fcntl.ioctl(sock.fileno(), _FIONBIO, struct.pack('L', 1))
- except OSError as exc:
- glog.exception(
- 'Exception caught while trying to make client nonblocking: ', exc)
- return sock
-
-
-def send_msg_8(sock, data):
- """Send 8 bytes of data over the socket.
- """
- sock.sendmsg([bytes(struct.pack('q', data))])
-
-
-def send_ctrl_msg(sock, fd, quad_data):
- sock.sendmsg([bytes(struct.pack('q', quad_data))],
- [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
- bytes(struct.pack('i', fd)))])
-
-
-def send_msg_utf8(sock, data):
- sock.sendall(bytes(data, encoding='ascii'))
-
-
-def recv_msg(sock, expected_length):
- chunks = []
- received = 0
- while received < expected_length:
- part = sock.recv(expected_length - received)
- received += len(part)
- chunks.append(part.decode(encoding='ascii'))
- data = ''.join(chunks)
- return data
diff --git a/launcher/clientconnection.py b/launcher/clientconnection.py
deleted file mode 100644
index 4734910..0000000
--- a/launcher/clientconnection.py
+++ /dev/null
@@ -1,88 +0,0 @@
-'''
- ClientConnection related.
-'''
-
-import glog
-
-from . import channel
-
-
-class ClientConnection():
- def __init__(self, client_socket, shmfd, layout_json, protocol_version=0):
- self.shmfd = shmfd
- self.client_socket = client_socket
- self.layout_json = layout_json
- self.proto_ver = protocol_version
-
- def handshake(self):
- #
- # ivshmem_client <--> ivshmem_server handshake.
- #
- # Client -> 'GET PROTOCOL_VER'
- # Server -> '0x000000000'
- # Client -> INFORM REGION_NAME_LEN: 0x0000000a
- # Client -> GET REGION: HW_COMPOSER
- # Server -> 0xffffffff(If region name not found)
- # Server -> 0xAABBC000 (region start offset)
- # Server -> 0xAABBC0000 (region end offset)
- # Server -> <Send cmsg with guest_to_host eventfd>
- # Server -> <Send cmsg with host_to_guest eventfd>
- # Server -> <Send cmsg with shmfd>
- #
-
- msg = channel.recv_msg(self.client_socket, len('GET PROTOCOL_VER'))
- glog.debug('server got %s' % msg)
- if msg == 'GET PROTOCOL_VER':
- channel.send_msg_utf8(self.client_socket, '0x00000000')
-
- msg = channel.recv_msg(self.client_socket,
- len('INFORM REGION_NAME_LEN: 0xAABBCCDD'))
- glog.debug('server got %s' % msg)
-
- if msg[:len('INFORM REGION_NAME_LEN: 0x')] == 'INFORM REGION_NAME_LEN: 0x':
- region_name_len = int(
- msg[len('INFORM REGION_NAME_LEN: '):], base=16)
- glog.debug(region_name_len)
-
- msg = channel.recv_msg(self.client_socket, region_name_len)
- glog.debug('server got region_name: %s' % msg)
-
- device_region = None
- for vsoc_device_region in self.layout_json['vsoc_device_regions']:
- # TODO:
- # read from the shared memory.
- if vsoc_device_region['device_name'] == msg:
- glog.debug('found region for %s' % msg)
- device_region = vsoc_device_region
-
- if device_region:
- # Send region start offset
- channel.send_msg_utf8(self.client_socket,
- '0x%08x' %
- int(device_region['region_begin_offset']))
- # Send region end offset
- channel.send_msg_utf8(self.client_socket,
- '0x%08x' %
- int(device_region['region_end_offset']))
- else:
- # send MAX_UINT32 if region not found.
- channel.send_msg_utf8(self.client_socket, '0xffffffff')
- self.client_socket.close()
- glog.debug('Closing connection')
- # TODO:
- # Raise a suitable Exception.
- return
-
- glog.debug('sending guest to host eventfd to client:')
- glog.debug(device_region['eventfds']['guest_to_host'])
- eventfd = device_region['eventfds']['guest_to_host']
- channel.send_ctrl_msg(self.client_socket, eventfd.fileno(), 0)
-
- glog.debug('sending host to guest eventfd to client:')
- eventfd = device_region['eventfds']['host_to_guest']
- channel.send_ctrl_msg(self.client_socket, eventfd.fileno(), 0)
-
- glog.debug('server sending shm fd %d' % self.shmfd)
- channel.send_ctrl_msg(self.client_socket, self.shmfd, 0)
- glog.info('server closing connection')
- self.client_socket.close()
diff --git a/launcher/ivserver.py b/launcher/ivserver.py
index ea9730e..9297b0b 100644
--- a/launcher/ivserver.py
+++ b/launcher/ivserver.py
@@ -6,107 +6,11 @@
import argparse
import json
import os
-import select
import signal
import sys
-import threading
import glog
from .libvirt_client import LibVirtClient
from .guest_definition import GuestDefinition
-from . import clientconnection
-from . import channel
-from . import vmconnection
-from . import vsocsharedmem
-
-class IVServer(object):
- def __init__(self, region_name, region_size,
- vm_socket_path, client_socket_path, layout_json):
- self.layout_json = layout_json
-
- # Create the SharedMemory. Linux zeroes out the contents initially.
- self.shmobject = vsocsharedmem.VSOCSharedMemory(region_size, region_name)
-
- # Populate the shared memory with the data from layout description.
- self.shmobject.create_layout(self.layout_json)
-
- # get the number of vectors. This will be passed to qemu.
- self.num_vectors = self.get_vector_count()
-
- # Establish the listener socket for QEMU.
- self.vm_listener_socket_path = vm_socket_path
- self.vm_listener_socket = channel.start_listener(vm_socket_path)
-
- # Establish the listener socket for Clients.
- self.client_listener_socket = channel.start_listener(client_socket_path)
-
- self.vm_connection = None
- self.client_connection = None
-
- # _control_channel and _thread_channel are two ends of the same, control pipe.
- # _thread_channel will be used by the serving thread until pipe is closed.
- (self._control_channel, self._thread_channel) = os.pipe()
- self._thread = threading.Thread(target=self._serve_in_background)
-
- def get_vector_count(self):
- # TODO: Parse from json instead of picking it up from shmobject.
- return self.shmobject.num_vectors
-
- def get_socket_path(self):
- return self.vm_listener_socket_path
-
- def serve(self):
- """Begin serving IVShMem data to QEmu.
- """
- self._thread.start()
-
- def stop(self):
- """Stop serving data to QEmu and join the serving thread.
- """
- os.close(self._control_channel)
- self._thread.join()
-
- def _serve_in_background(self):
- readfdlist = [
- self.vm_listener_socket,
- self.client_listener_socket,
- self._thread_channel
- ]
-
- while True:
- readable, _, _ = select.select(readfdlist, [], [])
-
- for client in readable:
- if client == self.vm_listener_socket:
- self.handle_new_vm_connection(client)
- elif client == self.client_listener_socket:
- self.handle_new_client_connection(client)
- elif client == self._thread_channel:
- # For now we do not expect any communication over pipe.
- # Since this bit of code is going away, we'll just assume
- # that the parent wants the thread to exit.
- return
-
-
- def handle_new_client_connection(self, listenersocket):
- client_socket = channel.handle_new_connection(listenersocket,
- nonblocking=False)
- self.client_connection = \
- clientconnection.ClientConnection(client_socket,
- self.shmobject.posix_shm.fd,
- self.layout_json,
- 0)
- self.client_connection.handshake()
-
- def handle_new_vm_connection(self, listenersocket):
- vm_socket = channel.handle_new_connection(listenersocket)
- self.vm_connection = vmconnection.VMConnection(self.layout_json,
- self.shmobject.posix_shm,
- vm_socket,
- self.num_vectors,
- hostid=0,
- vmid=1)
- self.vm_connection.handshake()
-
def setup_arg_parser():
def unsigned_integer(size):
@@ -119,6 +23,8 @@
parser.add_argument('-c', '--cpu', type=unsigned_integer, default=2,
help='Number of cpus to use in the guest')
parser.add_argument('-C', '--client', type=str,
+ help = 'Location of the HALD client socket, ' +
+ 'default=/tmp/ivshmem_socket_client',
default='/tmp/ivshmem_socket_client')
parser.add_argument('-i', '--image_dir', type=str, required=True,
help='Path to the directory of image files for the guest')
@@ -128,12 +34,8 @@
parser.add_argument('-L', '--layoutfile', type=str, required=True)
parser.add_argument('-M', '--memory', type=unsigned_integer, default=2048,
help='Size of the non-shared guest RAM in MiB')
- parser.add_argument('-N', '--name', type=str, default='ivshmem',
- help='Name of the POSIX shared memory segment')
- parser.add_argument('-P', '--path', type=str, default='/tmp/ivshmem_socket',
- help='Path to UNIX Domain Socket, default=/tmp/ivshmem_socket')
- parser.add_argument('-S', '--size', type=unsigned_integer, default=4,
- help='Size of shared memory region in MiB, default=4MiB')
+ parser.add_argument('-P', '--path', type=str, default='/tmp/ivshmem_socket_qemu',
+ help='Location of the QEmu socket, default=/tmp/ivshmem_socket_qemu')
return parser
@@ -153,7 +55,6 @@
lvc = LibVirtClient()
layout_json = json.loads(open(args.layoutfile).read())
- ivshmem_server = IVServer(args.name, args.size, args.path, args.client, layout_json)
if 'movbe' not in lvc.get_cpu_features():
glog.warning('host CPU may not support movbe instruction')
@@ -173,14 +74,11 @@
guest.set_cf_cache_path(os.path.join(args.image_dir, 'cache.img'))
guest.set_net_mobile_bridge('abr0')
- guest.set_ivshmem_vectors(ivshmem_server.get_vector_count())
- guest.set_ivshmem_socket_path(ivshmem_server.get_socket_path())
+ guest.set_ivshmem_vectors(len(layout_json['vsoc_device_regions']))
+ guest.set_ivshmem_socket_path(args.path)
guest.set_vmm_path(layout_json['guest']['vmm_path'])
- # Accept and process IVShMem connections from QEmu.
- ivshmem_server.serve()
-
glog.info('Creating virtual instance...')
dom = lvc.create_instance(guest.to_xml())
glog.info('VM ready.')
@@ -190,7 +88,6 @@
except KeyboardInterrupt:
glog.info('Stopping IVShMem server')
dom.destroy()
- ivshmem_server.stop()
except Exception as exception:
diff --git a/launcher/test_client.py b/launcher/test_client.py
deleted file mode 100644
index 8778423..0000000
--- a/launcher/test_client.py
+++ /dev/null
@@ -1,61 +0,0 @@
-import array
-import struct
-import socket
-import os
-
-from . import channel
-
-def recv_fd(conn):
-
- msg, ancdata, flags, addr = conn.recvmsg(struct.calcsize('q'),
- socket.CMSG_SPACE(struct.calcsize('i')))
- cmsg_level, cmsg_type, cmsg_data = ancdata[0]
- fda = array.array('I')
- fda.frombytes(cmsg_data)
- return fda[0]
-
-
-def startclient(client_name, socket_path):
- conn = channel.connect_to_channel(socket_path)
- print('client sending: GET PROTOCOL_VER')
- channel.send_msg_utf8(conn, 'GET PROTOCOL_VER')
- proto_ver = channel.recv_msg(conn,len('0xAABBCCDD'))
- print('client got: %s' % proto_ver)
- region_name_str_len = "0x%08x" % len(client_name)
-
- print('client sending: ' + 'INFORM REGION_NAME_LEN: %s' % region_name_str_len)
- channel.send_msg_utf8(conn, 'INFORM REGION_NAME_LEN: %s' % region_name_str_len)
-
- print('client sending: ' + client_name)
- channel.send_msg_utf8(conn, client_name)
-
- region_start_offset = channel.recv_msg(conn, len('0xAABBCCDD'))
- print('client got region_start_offset: %s' % region_start_offset)
-
- region_end_offset = channel.recv_msg(conn, len('0xAABBCCDD'))
- print('client got region_end_offset: %s' % region_end_offset)
-
- print('client waiting for node count')
- node_count = channel.recv_msg(conn, len('0xAABBCCDD'))
- print("node count %s" % node_count)
- for node in range(int(node_count, base=16)):
- print('TODO: client waiting for lock offsets for node %d' % node)
-
- print('client waiting for guest_to_host eventfd')
- fd = recv_fd(conn)
- print('guest_to_host eventfd %d' % fd)
-
- print('client waiting for host_to_guest eventfd')
- fd = recv_fd(conn)
- print('host_to_guest eventfd %d' % fd)
-
- print('client waiting for shm descriptor')
- fd = recv_fd(conn)
-
- #size is in [6]th position of tuple
- print('shm size is %d MB' % (os.fstat(fd)[6] >> 20))
-
-
-if __name__ == '__main__':
- startclient('HWCOMPOSER', '/tmp/ivshmem_socket_client')
-
diff --git a/launcher/vmconnection.py b/launcher/vmconnection.py
deleted file mode 100644
index 5679e3c..0000000
--- a/launcher/vmconnection.py
+++ /dev/null
@@ -1,34 +0,0 @@
-'''
- VMConnection related.
-'''
-
-import linuxfd
-
-from . import channel
-
-class VMConnection():
- def __init__(self, layout_json, posix_shm, vm_socket, vector_count, hostid,
- vmid, protocol_version=0):
- self.hostid = hostid
- self.vmid = vmid
- self.shm = posix_shm
- self.vm_socket = vm_socket
- self.nvecs = vector_count
- self.proto_ver = protocol_version
- self.layout_json = layout_json
-
- def handshake(self):
- channel.send_msg_8(self.vm_socket, self.proto_ver)
- channel.send_msg_8(self.vm_socket, self.vmid)
- channel.send_ctrl_msg(self.vm_socket, self.shm.fd, -1)
-
- # send the eventfds
- for region in self.layout_json['vsoc_device_regions']:
- eventfd = region['eventfds']['host_to_guest']
- channel.send_ctrl_msg(self.vm_socket, eventfd.fileno(), self.vmid)
-
- for region in self.layout_json['vsoc_device_regions']:
- eventfd = region['eventfds']['guest_to_host']
- channel.send_ctrl_msg(self.vm_socket, eventfd.fileno(), self.hostid)
-
-
diff --git a/launcher/vsoc_mem.json b/launcher/vsoc_mem.json
deleted file mode 100644
index eab8805..0000000
--- a/launcher/vsoc_mem.json
+++ /dev/null
@@ -1,109 +0,0 @@
-{
- "guest": {
- "vmm_path": "/usr/bin/qemu-system-x86_64",
- "kernel_command_line" : [
- "loop.max_part=7",
- "console=ttyS0",
- "androidboot.console=ttyS0",
- "androidboot.hardware=vsoc",
- "security=selinux",
- "androidboot.selinux=permissive",
- "enforcing=0",
- "audit=0",
- "CUTTLEFISH"
- ]
- },
-
- "version" : "1",
- "__comment" : "The first page should be reserved for top level headers and region descriptors only",
- "size" : "4194304",
- "region_count" : "4",
-
- "vsoc_shm_layout_descriptor" : {
- "__comment": "The top level layout descriptor",
- "size": "<populated by querying the shm region size at runtime>",
- "region_count" : "4",
- "vsoc_region_desc_offset" : "128"
- },
-
- "vsoc_device_regions" : [
- {
- "__comment" : "Primary end to end test region",
- "current_version" : "1",
- "min_compatible_version" : "1",
- "region_begin_offset" : "4096",
- "region_end_offset" : "8192",
-
- "guest_to_host_signal_table" : {
- "__comment" : "",
- "num_nodes_lg2" : "2"
- },
-
- "host_to_guest_signal_table" : {
- "__comment" : "",
- "num_nodes_lg2" : "2"
- },
-
- "device_name" : "e2e_primary"
- },
-
- {
- "__comment" : "HWComposer",
- "current_version" : "1",
- "min_compatible_version" : "1",
- "region_begin_offset" : "8192",
- "region_end_offset" : "16384",
-
- "guest_to_host_signal_table" : {
- "__comment" : "",
- "num_nodes_lg2" : "2"
- },
-
- "host_to_guest_signal_table" : {
- "__comment" : "",
- "num_nodes_lg2" : "2"
- },
-
- "device_name" : "hwcomposer"
- },
-
- {
- "__comment" : "Sensors",
- "current_version" : "1",
- "min_compatible_version" : "1",
- "region_begin_offset" : "16384",
- "region_end_offset" : "32768",
-
- "guest_to_host_signal_table" : {
- "__comment" : "each node is the size of a unit32_t. See vsoc_shm.h line 81",
- "num_nodes_lg2" : "1"
- },
-
- "host_to_guest_signal_table" : {
- "__comment" : "",
- "num_nodes_lg2" : "1"
- },
-
- "device_name" : "sensors"
- },
- {
- "__comment" : "e2e_secondary",
- "current_version" : "1",
- "min_compatible_version" : "1",
- "region_begin_offset" : "32768",
- "region_end_offset" : "36864",
-
- "guest_to_host_signal_table" : {
- "__comment" : "",
- "num_nodes_lg2" : "1"
- },
-
- "host_to_guest_signal_table" : {
- "__comment" : "",
- "num_nodes_lg2" : "1"
- },
-
- "device_name" : "e2e_secondary"
- }
- ]
-}
diff --git a/launcher/vsocsharedmem.py b/launcher/vsocsharedmem.py
deleted file mode 100644
index d444428..0000000
--- a/launcher/vsocsharedmem.py
+++ /dev/null
@@ -1,101 +0,0 @@
-'''
- VSOC Shared Memory backed by POSIX shared memory.
- Also creates the initial vSOC layout.
-'''
-
-import linuxfd
-import mmap
-import os
-import posix_ipc
-import struct
-
-class VSOCSharedMemory():
- def __init__(self, size, name='ivshmem'):
- self.shm_size = size << 20
- self.posix_shm = None
- self.create_posix_shm(size, name)
- self.num_vectors = 0
-
- def create_posix_shm(self, size, name='ivshmem'):
- self.posix_shm = posix_ipc.SharedMemory(name,
- flags=os.O_CREAT,
- size=self.shm_size)
-
- def create_layout(self, layout, major_version=1, minor_version=0):
- offset = 0
- shmmap = mmap.mmap(self.posix_shm.fd, 0)
-
- #
- # shared memory layout based on
- # project: kernel/private/gce_x86
- # file: drivers/staging/android/uapi/vsoc_shm.h
- # commit-id: 2bc0d6b47c4a8d8204faecb7016af09a28e8c3ad
- # TODO:
- # We need a way to synchronize the changes in the
- # sources with the packing below.
- #
-
- header_struct = struct.Struct('HHIII')
- header_struct.pack_into(shmmap, offset,
- major_version,
- minor_version,
- shmmap.size(),
- int(layout['vsoc_shm_layout_descriptor']
- ['region_count']),
- int(layout['vsoc_shm_layout_descriptor']
- ['vsoc_region_desc_offset'])
- )
- region_descriptor_offset = int(layout['vsoc_shm_layout_descriptor']
- ['vsoc_region_desc_offset'])
- offset += region_descriptor_offset
-
- vsoc_device_struct = struct.Struct('HHIIIIIIIII16s')
-
- for region in layout['vsoc_device_regions']:
- self.num_vectors += 1
-
- region['eventfds'] = {}
- region['eventfds']['guest_to_host'] = \
- linuxfd.eventfd(initval=0,
- semaphore=False,
- nonBlocking=True,
- closeOnExec=True)
-
- region['eventfds']['host_to_guest'] = \
- linuxfd.eventfd(initval=0,
- semaphore=False,
- nonBlocking=False,
- closeOnExec=True)
- # Calculate the offsets
- # Compensate for the fixed bits of the region header
- current_offset = 56
- region['guest_to_host_signal_table']['offset'] = current_offset
- current_offset += 4 * (1 << int(region['guest_to_host_signal_table']['num_nodes_lg2']))
- region['guest_to_host_signal_table']['node_alloc_hint_offset'] = current_offset
- current_offset += 4
- region['host_to_guest_signal_table']['offset'] = current_offset
- current_offset += 4 * (1 << int(region['host_to_guest_signal_table']['num_nodes_lg2']))
- region['host_to_guest_signal_table']['node_alloc_hint_offset'] = current_offset
- current_offset += 4
- region['offset_of_region_data'] = current_offset
- vsoc_device_struct. \
- pack_into(shmmap, offset,
- int(region['current_version']),
- int(region['min_compatible_version']),
- int(region['region_begin_offset']),
- int(region['region_end_offset']),
- region['offset_of_region_data'],
- int(region['guest_to_host_signal_table']['num_nodes_lg2']),
- region['guest_to_host_signal_table']['offset'],
- region['guest_to_host_signal_table']['node_alloc_hint_offset'],
- int(region['host_to_guest_signal_table']['num_nodes_lg2']),
- region['host_to_guest_signal_table']['offset'],
- region['host_to_guest_signal_table']['node_alloc_hint_offset'],
- bytes(region['device_name'], encoding='ascii')
- )
- offset += vsoc_device_struct.size
-
- # We need atleast one vector to start QEMU.
- # TODO: Perhaps throw an exception here and bail out early.
- if self.num_vectors == 0:
- self.num_vectors = 1