summaryrefslogtreecommitdiffstats
path: root/src/vpp-api/python/vpp_papi
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2018-10-22 09:30:26 +0200
committerDamjan Marion <dmarion@me.com>2018-10-22 11:52:20 +0000
commit31555a3475a37195938378217a635b3451e449de (patch)
treeb330d858fe6d8f1a0b236b608e8970d5114e015c /src/vpp-api/python/vpp_papi
parent430634c457da5dd04f481da0118bab581ace732e (diff)
PAPI: Add support for format/unformat functions.
With the introduction of new types, like vl_api_address_t it is now possible to call a message using one of those functions with a string representation. E.g. for an IP address ip_add_address(address="1.1.1.1/24") The language wrapper will automatically convert the string into the vl_api_address_t representation. Currently the caller must do the reverse conversion from the returned named tuple with the unformat function. rv = get_address_on_interface(sw_if_index=1) print(VPPFormat.unformat(rv.address)) Change-Id: Ic872b4560b2f4836255bd5260289bfa38c75bc5d Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/vpp-api/python/vpp_papi')
-rwxr-xr-xsrc/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py64
-rw-r--r--src/vpp-api/python/vpp_papi/vpp_format.py144
-rw-r--r--src/vpp-api/python/vpp_papi/vpp_papi.py1
-rw-r--r--src/vpp-api/python/vpp_papi/vpp_serializer.py41
-rw-r--r--src/vpp-api/python/vpp_papi/vpp_stats.py9
5 files changed, 247 insertions, 12 deletions
diff --git a/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py b/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py
index 4e8a417c6fd..4b47e1eca7d 100755
--- a/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py
+++ b/src/vpp-api/python/vpp_papi/tests/test_vpp_serializer.py
@@ -3,6 +3,7 @@
import unittest
from vpp_papi.vpp_serializer import VPPType, VPPEnumType
from vpp_papi.vpp_serializer import VPPUnionType, VPPMessage
+from vpp_papi.vpp_format import VPPFormat
from socket import inet_pton, AF_INET, AF_INET6
import logging
import sys
@@ -89,6 +90,65 @@ class TestAddType(unittest.TestCase):
nt, size = message_with_va_address_list.unpack(b)
self.assertEqual(nt.is_cool, 100)
+ def test_recursive_address(self):
+ af = VPPEnumType('vl_api_address_family_t', [["ADDRESS_IP4", 0],
+ ["ADDRESS_IP6", 1],
+ {"enumtype": "u32"}])
+ ip4 = VPPType('vl_api_ip4_address_t', [['u8', 'address', 4]])
+ ip6 = VPPType('vl_api_ip6_address_t', [['u8', 'address', 16]])
+ VPPUnionType('vl_api_address_union_t',
+ [["vl_api_ip4_address_t", "ip4"],
+ ["vl_api_ip6_address_t", "ip6"]])
+
+ address = VPPType('vl_api_address_t',
+ [['vl_api_address_family_t', 'af'],
+ ['vl_api_address_union_t', 'un']])
+
+ prefix = VPPType('vl_api_prefix_t',
+ [['vl_api_address_t', 'address'],
+ ['u8', 'address_length']])
+ message = VPPMessage('svs',
+ [['vl_api_prefix_t', 'prefix']])
+ message_addr = VPPMessage('svs_address',
+ [['vl_api_address_t', 'address']])
+
+
+ b = message_addr.pack({'address': "1::1"})
+ self.assertEqual(len(b), 20)
+ nt, size = message_addr.unpack(b)
+ self.assertEqual("1::1", VPPFormat.unformat(nt.address))
+ b = message_addr.pack({'address': "1.1.1.1"})
+ self.assertEqual(len(b), 20)
+ nt, size = message_addr.unpack(b)
+ self.assertEqual("1.1.1.1", VPPFormat.unformat(nt.address))
+
+ b = message.pack({'prefix': "1.1.1.1/24"})
+ self.assertEqual(len(b), 21)
+ nt, size = message.unpack(b)
+ self.assertEqual("1.1.1.1/24", VPPFormat.unformat(nt.prefix))
+
+ def test_zero_vla(self):
+ '''Default zero'ed out for VLAs'''
+ list = VPPType('vl_api_list_t',
+ [['u8', 'count', 10]])
+
+ # Define an embedded VLA type
+ valist = VPPType('vl_api_valist_t',
+ [['u8', 'count'],
+ ['u8', 'string', 0, 'count']])
+ # Define a message
+ vamessage = VPPMessage('vamsg',
+ [['vl_api_valist_t', 'valist'],
+ ['u8', 'is_something']])
+
+ message = VPPMessage('msg',
+ [['vl_api_list_t', 'list'],
+ ['u8', 'is_something']])
+
+ # Pack message without VLA specified
+ b = message.pack({'is_something': 1})
+ b = vamessage.pack({'is_something': 1})
+
def test_arrays(self):
# Test cases
# 1. Fixed list
@@ -133,7 +193,7 @@ class TestAddType(unittest.TestCase):
inet_pton(AF_INET, '2.2.2.2'))
string = 'foobar foobar'
- b = s.pack({'length': len(string), 'string': string})
+ b = s.pack({'length': len(string), 'string': string.encode()})
nt, size = s.unpack(b)
self.assertEqual(len(b), size)
@@ -142,7 +202,7 @@ class TestAddType(unittest.TestCase):
['u8', 'string', 0, 'length']])
string = ''
- b = s.pack({'length': len(string), 'string': string})
+ b = s.pack({'length': len(string), 'string': string.encode()})
nt, size = s.unpack(b)
self.assertEqual(len(b), size)
diff --git a/src/vpp-api/python/vpp_papi/vpp_format.py b/src/vpp-api/python/vpp_papi/vpp_format.py
new file mode 100644
index 00000000000..b1800d87dd1
--- /dev/null
+++ b/src/vpp-api/python/vpp_papi/vpp_format.py
@@ -0,0 +1,144 @@
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from socket import inet_pton, inet_ntop, AF_INET6, AF_INET
+
+
+class VPPFormat:
+ @staticmethod
+ def format_vl_api_ip6_prefix_t(args):
+ prefix, len = args.split('/')
+ return {'prefix': {'address': inet_pton(AF_INET6, prefix)},
+ 'len': int(len)}
+
+ @staticmethod
+ def unformat_vl_api_ip6_prefix_t(args):
+ return "{}/{}".format(inet_ntop(AF_INET6, args.prefix.address),
+ args.len)
+
+ @staticmethod
+ def format_vl_api_ip4_prefix_t(args):
+ prefix, len = args.split('/')
+ return {'prefix': {'address': inet_pton(AF_INET, prefix)},
+ 'len': int(len)}
+
+ @staticmethod
+ def unformat_vl_api_ip4_prefix_t(args):
+ return "{}/{}".format(inet_ntop(AF_INET, args.prefix.address),
+ args.len)
+
+ @staticmethod
+ def format_vl_api_ip6_address_t(args):
+ return {'address': inet_pton(AF_INET6, args)}
+
+ @staticmethod
+ def format_vl_api_ip4_address_t(args):
+ return {'address': inet_pton(AF_INET, args)}
+
+ @staticmethod
+ def format_vl_api_address_t(args):
+ try:
+ return {'un': {'ip6': {'address': inet_pton(AF_INET6, args)}},
+ 'af': int(1)}
+ except Exception as e:
+ return {'un': {'ip4': {'address': inet_pton(AF_INET, args)}},
+ 'af': int(0)}
+
+ @staticmethod
+ def unformat_vl_api_address_t(arg):
+ if arg.af == 1:
+ return inet_ntop(AF_INET6, arg.un.ip6.address)
+ if arg.af == 0:
+ return inet_ntop(AF_INET, arg.un.ip4.address)
+ raise
+
+ @staticmethod
+ def format_vl_api_prefix_t(args):
+ prefix, len = args.split('/')
+ return {'address': VPPFormat.format_vl_api_address_t(prefix),
+ 'address_length': int(len)}
+
+ @staticmethod
+ def unformat_vl_api_prefix_t(arg):
+ if arg.address.af == 1:
+ return "{}/{}".format(inet_ntop(AF_INET6,
+ arg.address.un.ip6.address),
+ arg.address_length)
+ if arg.address.af == 0:
+ return "{}/{}".format(inet_ntop(AF_INET,
+ arg.address.un.ip4.address),
+ arg.address_length)
+ raise
+
+ @staticmethod
+ def format_u8(args):
+ try:
+ return int(args)
+ except Exception as e:
+ return args.encode()
+
+ @staticmethod
+ def format(typename, args):
+ try:
+ return getattr(VPPFormat, 'format_' + typename)(args)
+ except AttributeError:
+ # Default
+ return (int(args))
+
+ @staticmethod
+ def unformat_bytes(args):
+ try:
+ return args.decode('utf-8')
+ except Exception as e:
+ return args
+
+ @staticmethod
+ def unformat_list(args):
+ s = '['
+ for f in args:
+ t = type(f).__name__
+ if type(f) is int:
+ s2 = str(f)
+ else:
+ s2 = VPPFormat.unformat_t(t, f)
+ s += '{} '.format(s2)
+ return s[:-1] + ']'
+
+ @staticmethod
+ def unformat(args):
+ s = ''
+ return VPPFormat.unformat_t(type(args).__name__, args)
+ '''
+ for i, f in enumerate(args):
+ print('F', f)
+ t = type(f).__name__
+ if type(f) is int:
+ s2 = str(f)
+ else:
+ s2 = VPPFormat.unformat_t(t, f)
+ s += '{} {} '.format(args._fields[i], s2)
+ return s[:-1]
+ '''
+
+ @staticmethod
+ def unformat_t(typename, args):
+ try:
+ return getattr(VPPFormat, 'unformat_' + typename)(args)
+ except AttributeError:
+ # Type without explicit override
+ return VPPFormat.unformat(args)
+
+ # Default handling
+ return args
diff --git a/src/vpp-api/python/vpp_papi/vpp_papi.py b/src/vpp-api/python/vpp_papi/vpp_papi.py
index 5e98f92cecd..2310cd1e455 100644
--- a/src/vpp-api/python/vpp_papi/vpp_papi.py
+++ b/src/vpp-api/python/vpp_papi/vpp_papi.py
@@ -28,6 +28,7 @@ import weakref
import atexit
from . vpp_serializer import VPPType, VPPEnumType, VPPUnionType, BaseTypes
from . vpp_serializer import VPPMessage, vpp_get_type
+from . vpp_format import VPPFormat
if sys.version[0] == '2':
import Queue as queue
diff --git a/src/vpp-api/python/vpp_papi/vpp_serializer.py b/src/vpp-api/python/vpp_papi/vpp_serializer.py
index 240912d96ba..8635ce0070c 100644
--- a/src/vpp-api/python/vpp_papi/vpp_serializer.py
+++ b/src/vpp-api/python/vpp_papi/vpp_serializer.py
@@ -17,6 +17,7 @@ import struct
import collections
from enum import IntEnum
import logging
+from .vpp_format import VPPFormat
#
# Set log-level in application by doing e.g.:
@@ -46,6 +47,8 @@ class BaseTypes():
.format(type, base_types[type]))
def pack(self, data, kwargs=None):
+ if not data: # Default to zero if not specified
+ data = 0
return self.packer.pack(data)
def unpack(self, data, offset, result=None):
@@ -79,6 +82,8 @@ class FixedList_u8():
def pack(self, list, kwargs):
"""Packs a fixed length bytestring. Left-pads with zeros
if input data is too short."""
+ if not list:
+ return b'\x00' * self.size
if len(list) > self.num:
raise ValueError('Fixed list length error for "{}", got: {}'
' expected: {}'
@@ -129,6 +134,8 @@ class VLAList():
self.length_field = len_field_name
def pack(self, list, kwargs=None):
+ if not list:
+ return b""
if len(list) != kwargs[self.length_field]:
raise ValueError('Variable length error, got: {} expected: {}'
.format(len(list), kwargs[self.length_field]))
@@ -213,7 +220,7 @@ class VPPEnumType():
return True
def pack(self, data, kwargs=None):
- return types['u32'].pack(data, kwargs)
+ return types['u32'].pack(data)
def unpack(self, data, offset=0, result=None):
x, size = types['u32'].unpack(data, offset)
@@ -246,7 +253,11 @@ class VPPUnionType():
self.tuple = collections.namedtuple(name, fields, rename=True)
logger.debug('Adding union {}'.format(name))
+ # Union of variable length?
def pack(self, data, kwargs=None):
+ if not data:
+ return b'\x00' * self.size
+
for k, v in data.items():
logger.debug("Key: {} Value: {}".format(k, v))
b = self.packers[k].pack(v, kwargs)
@@ -319,14 +330,32 @@ class VPPType():
kwargs = data
b = bytes()
for i, a in enumerate(self.fields):
- if a not in data:
- b += b'\x00' * self.packers[i].size
- continue
+
+ # Try one of the format functions
+ if data and type(data) is not dict and a not in data:
+ raise ValueError("Invalid argument: {} expected {}.{}".
+ format(data, self.name, a))
+
+ # Defaulting to zero.
+ if not data or a not in data: # Default to 0
+ arg = None
+ kwarg = None # No default for VLA
+ else:
+ arg = data[a]
+ kwarg = kwargs[a] if a in kwargs else None
if isinstance(self.packers[i], VPPType):
- b += self.packers[i].pack(data[a], kwargs[a])
+ try:
+ b += self.packers[i].pack(arg, kwarg)
+ except ValueError:
+ # Invalid argument, can we convert it?
+ arg = VPPFormat.format(self.packers[i].name, data[a])
+ data[a] = arg
+ kwarg = arg
+ b += self.packers[i].pack(arg, kwarg)
else:
- b += self.packers[i].pack(data[a], kwargs)
+ b += self.packers[i].pack(arg, kwargs)
+
return b
def unpack(self, data, offset=0, result=None):
diff --git a/src/vpp-api/python/vpp_papi/vpp_stats.py b/src/vpp-api/python/vpp_papi/vpp_stats.py
index 8c1aaf2b87a..76e1e5435f0 100644
--- a/src/vpp-api/python/vpp_papi/vpp_stats.py
+++ b/src/vpp-api/python/vpp_papi/vpp_stats.py
@@ -62,7 +62,8 @@ def make_string_vector(api, strings):
if type(strings) is not list:
strings = [strings]
for s in strings:
- vec = api.stat_segment_string_vector(vec, ffi.new("char []", s.encode()))
+ vec = api.stat_segment_string_vector(vec, ffi.new("char []",
+ s.encode()))
return vec
@@ -134,7 +135,7 @@ class VPPStats:
for i in range(rv_len):
n = ffi.string(rv[i].name).decode()
e = stat_entry_to_python(self.api, rv[i])
- if e != None:
+ if e is not None:
stats[n] = e
return stats
@@ -144,7 +145,7 @@ class VPPStats:
try:
dir = self.ls(name)
return self.dump(dir).values()[0]
- except:
+ except Exception as e:
if retries > 10:
return None
retries += 1
@@ -161,7 +162,7 @@ class VPPStats:
error_names = self.ls(['/err/'])
error_counters = self.dump(error_names)
break
- except:
+ except Exception as e:
if retries > 10:
return None
retries += 1
class="k">if (svm_get_root_rp ()) { /* TODO: is this really needed? */ svm_main_region_t *smr = svm_get_root_rp ()->data_base; if (fchown (ssvm_fd, smr->uid, smr->gid) < 0) clib_unix_warning ("ssvm segment chown"); } if (lseek (ssvm_fd, ssvm->ssvm_size, SEEK_SET) < 0) { clib_unix_warning ("lseek"); close (ssvm_fd); return SSVM_API_ERROR_SET_SIZE; } if (write (ssvm_fd, &junk, 1) != 1) { clib_unix_warning ("set ssvm size"); close (ssvm_fd); return SSVM_API_ERROR_SET_SIZE; } page_size = clib_mem_get_fd_page_size (ssvm_fd); if (ssvm->requested_va) { requested_va = ssvm->requested_va; clib_mem_vm_randomize_va (&requested_va, min_log2 (page_size)); } mapa.requested_va = requested_va; mapa.size = ssvm->ssvm_size; mapa.fd = ssvm_fd; if (clib_mem_vm_ext_map (&mapa)) { clib_unix_warning ("mmap"); close (ssvm_fd); return SSVM_API_ERROR_MMAP; } close (ssvm_fd); sh = mapa.addr; sh->master_pid = ssvm->my_pid; sh->ssvm_size = ssvm->ssvm_size; sh->ssvm_va = pointer_to_uword (sh); sh->type = SSVM_SEGMENT_SHM; #if USE_DLMALLOC == 0 sh->heap = mheap_alloc_with_flags (((u8 *) sh) + page_size, ssvm->ssvm_size - page_size, mh_flags); #else sh->heap = create_mspace_with_base (((u8 *) sh) + page_size, ssvm->ssvm_size - page_size, 1 /* locked */ ); mspace_disable_expand (sh->heap); #endif oldheap = ssvm_push_heap (sh); sh->name = format (0, "%s", ssvm->name, 0); ssvm_pop_heap (oldheap); ssvm->sh = sh; ssvm->my_pid = getpid (); ssvm->i_am_master = 1; /* The application has to set set sh->ready... */ return 0; } int ssvm_slave_init_shm (ssvm_private_t * ssvm) { struct stat stat; int ssvm_fd = -1; ssvm_shared_header_t *sh; ASSERT (vec_c_string_is_terminated (ssvm->name)); ssvm->i_am_master = 0; while (ssvm->attach_timeout-- > 0) { if (ssvm_fd < 0) ssvm_fd = shm_open ((char *) ssvm->name, O_RDWR, 0777); if (ssvm_fd < 0) { sleep (1); continue; } if (fstat (ssvm_fd, &stat) < 0) { sleep (1); continue; } if (stat.st_size > 0) goto map_it; } clib_warning ("slave timeout"); return SSVM_API_ERROR_SLAVE_TIMEOUT; map_it: sh = (void *) mmap (0, MMAP_PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, ssvm_fd, 0); if (sh == MAP_FAILED) { clib_unix_warning ("slave research mmap"); close (ssvm_fd); return SSVM_API_ERROR_MMAP; } while (ssvm->attach_timeout-- > 0) { if (sh->ready) goto re_map_it; } close (ssvm_fd); munmap (sh, MMAP_PAGESIZE); clib_warning ("slave timeout 2"); return SSVM_API_ERROR_SLAVE_TIMEOUT; re_map_it: ssvm->requested_va = (u64) sh->ssvm_va; ssvm->ssvm_size = sh->ssvm_size; munmap (sh, MMAP_PAGESIZE); sh = ssvm->sh = (void *) mmap ((void *) ssvm->requested_va, ssvm->ssvm_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, ssvm_fd, 0); if (sh == MAP_FAILED) { clib_unix_warning ("slave final mmap"); close (ssvm_fd); return SSVM_API_ERROR_MMAP; } sh->slave_pid = getpid (); return 0; } void ssvm_delete_shm (ssvm_private_t * ssvm) { u8 *fn; fn = format (0, "/dev/shm/%s%c", ssvm->name, 0); if (CLIB_DEBUG > 1) clib_warning ("[%d] unlinking ssvm (%s) backing file '%s'", getpid (), ssvm->name, fn); /* Throw away the backing file */ if (unlink ((char *) fn) < 0) clib_unix_warning ("unlink segment '%s'", ssvm->name); vec_free (fn); vec_free (ssvm->name); munmap ((void *) ssvm->requested_va, ssvm->ssvm_size); } /** * Initialize memfd segment master */ int ssvm_master_init_memfd (ssvm_private_t * memfd) { uword page_size; ssvm_shared_header_t *sh; void *oldheap; clib_mem_vm_alloc_t alloc = { 0 }; clib_error_t *err; if (memfd->ssvm_size == 0) return SSVM_API_ERROR_NO_SIZE; ASSERT (vec_c_string_is_terminated (memfd->name)); alloc.name = (char *) memfd->name; alloc.size = memfd->ssvm_size; alloc.flags = CLIB_MEM_VM_F_SHARED; alloc.requested_va = memfd->requested_va; if ((err = clib_mem_vm_ext_alloc (&alloc))) { clib_error_report (err); return SSVM_API_ERROR_CREATE_FAILURE; } memfd->fd = alloc.fd; memfd->sh = (ssvm_shared_header_t *) alloc.addr; memfd->my_pid = getpid (); memfd->i_am_master = 1; page_size = 1ull << alloc.log2_page_size; sh = memfd->sh; sh->master_pid = memfd->my_pid; sh->ssvm_size = memfd->ssvm_size; sh->ssvm_va = pointer_to_uword (sh); sh->type = SSVM_SEGMENT_MEMFD; #if USE_DLMALLOC == 0 uword flags = MHEAP_FLAG_DISABLE_VM | MHEAP_FLAG_THREAD_SAFE; sh->heap = mheap_alloc_with_flags (((u8 *) sh) + page_size, memfd->ssvm_size - page_size, flags); #else sh->heap = create_mspace_with_base (((u8 *) sh) + page_size, memfd->ssvm_size - page_size, 1 /* locked */ ); mspace_disable_expand (sh->heap); #endif oldheap = ssvm_push_heap (sh); sh->name = format (0, "%s", memfd->name, 0); ssvm_pop_heap (oldheap); /* The application has to set set sh->ready... */ return 0; } /** * Initialize memfd segment slave * * Subtly different than svm_slave_init. The caller needs to acquire * a usable file descriptor for the memfd segment e.g. via * vppinfra/socket.c:default_socket_recvmsg */ int ssvm_slave_init_memfd (ssvm_private_t * memfd) { clib_mem_vm_map_t mapa = { 0 }; ssvm_shared_header_t *sh; uword page_size; memfd->i_am_master = 0; page_size = clib_mem_get_fd_page_size (memfd->fd); if (!page_size) { clib_unix_warning ("page size unknown"); return SSVM_API_ERROR_MMAP; } /* * Map the segment once, to look at the shared header */ mapa.fd = memfd->fd; mapa.size = page_size; if (clib_mem_vm_ext_map (&mapa)) { clib_unix_warning ("slave research mmap (fd %d)", mapa.fd); close (memfd->fd); return SSVM_API_ERROR_MMAP; } sh = mapa.addr; memfd->requested_va = sh->ssvm_va; memfd->ssvm_size = sh->ssvm_size; clib_mem_vm_free (sh, page_size); /* * Remap the segment at the 'right' address */ mapa.requested_va = memfd->requested_va; mapa.size = memfd->ssvm_size; if (clib_mem_vm_ext_map (&mapa)) { clib_unix_warning ("slave final mmap"); close (memfd->fd); return SSVM_API_ERROR_MMAP; } sh = mapa.addr; sh->slave_pid = getpid (); memfd->sh = sh; return 0; } void ssvm_delete_memfd (ssvm_private_t * memfd) { vec_free (memfd->name); clib_mem_vm_free (memfd->sh, memfd->ssvm_size); close (memfd->fd); } /** * Initialize segment in a private heap */ int ssvm_master_init_private (ssvm_private_t * ssvm) { ssvm_shared_header_t *sh; u32 pagesize = clib_mem_get_page_size (); u32 rnd_size = 0; u8 *heap; rnd_size = (ssvm->ssvm_size + (pagesize - 1)) & ~(pagesize - 1); rnd_size = clib_min (rnd_size, ((u64) 1 << 32) - pagesize); #if USE_DLMALLOC == 0 { mheap_t *heap_header; heap = mheap_alloc (0, rnd_size); if (heap == 0) { clib_unix_warning ("mheap alloc"); return -1; } heap_header = mheap_header (heap); heap_header->flags |= MHEAP_FLAG_THREAD_SAFE; } #else heap = create_mspace (rnd_size, 1 /* locked */ ); #endif ssvm->ssvm_size = rnd_size; ssvm->i_am_master = 1; ssvm->my_pid = getpid (); ssvm->requested_va = ~0; /* Allocate a [sic] shared memory header, in process memory... */ sh = clib_mem_alloc_aligned (sizeof (*sh), CLIB_CACHE_LINE_BYTES); ssvm->sh = sh; clib_memset (sh, 0, sizeof (*sh)); sh->heap = heap; sh->type = SSVM_SEGMENT_PRIVATE; return 0; } int ssvm_slave_init_private (ssvm_private_t * ssvm) { clib_warning ("BUG: this should not be called!"); return -1; } void ssvm_delete_private (ssvm_private_t * ssvm) { vec_free (ssvm->name); #if USE_DLMALLOC == 0 mheap_free (ssvm->sh->heap); #else destroy_mspace (ssvm->sh->heap); #endif clib_mem_free (ssvm->sh); } int ssvm_master_init (ssvm_private_t * ssvm, ssvm_segment_type_t type) { return (master_init_fns[type]) (ssvm); } int ssvm_slave_init (ssvm_private_t * ssvm, ssvm_segment_type_t type) { return (slave_init_fns[type]) (ssvm); } void ssvm_delete (ssvm_private_t * ssvm) { delete_fns[ssvm->sh->type] (ssvm); } ssvm_segment_type_t ssvm_type (const ssvm_private_t * ssvm) { return ssvm->sh->type; } u8 * ssvm_name (const ssvm_private_t * ssvm) { return ssvm->sh->name; } /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */