diff options
author | Ed Warnicke <eaw@cisco.com> | 2015-12-08 15:45:58 -0700 |
---|---|---|
committer | Ed Warnicke <eaw@cisco.com> | 2015-12-08 15:47:27 -0700 |
commit | cb9cadad578297ffd78fa8a33670bdf1ab669e7e (patch) | |
tree | 6ac2be912482cc7849a26f0ab845561c3d7f4e26 /vpp/api/test_ha.c | |
parent | fb0815d4ae4bb0fe27bd9313f34b45c8593b907e (diff) |
Initial commit of vpp code.
Change-Id: Ib246f1fbfce93274020ee93ce461e3d8bd8b9f17
Signed-off-by: Ed Warnicke <eaw@cisco.com>
Diffstat (limited to 'vpp/api/test_ha.c')
-rw-r--r-- | vpp/api/test_ha.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/vpp/api/test_ha.c b/vpp/api/test_ha.c new file mode 100644 index 00000000..0c66394b --- /dev/null +++ b/vpp/api/test_ha.c @@ -0,0 +1,219 @@ +/* + *------------------------------------------------------------------ + * api.c - message handler registration + * + * Copyright (c) 2010 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. + *------------------------------------------------------------------ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <signal.h> +#include <pthread.h> +#include <unistd.h> +#include <time.h> +#include <fcntl.h> +#include <string.h> +#include <vppinfra/clib.h> +#include <vppinfra/vec.h> +#include <vppinfra/hash.h> +#include <vppinfra/bitmap.h> +#include <vppinfra/fifo.h> +#include <vppinfra/time.h> +#include <vppinfra/mheap.h> +#include <vppinfra/heap.h> +#include <vppinfra/pool.h> +#include <vppinfra/format.h> +#include <vppinfra/error.h> + +#include <vnet/vnet.h> +#include <vlib/vlib.h> +#include <vlib/unix/unix.h> +#include <vlibapi/api.h> +#include <vlibmemory/api.h> +#include <svm.h> +#include <svmdb.h> + +#include <api/vpe_msg_enum.h> + +#include <vnet/ip/ip.h> + +#define f64_endian(a) +#define f64_print(a,b) + +#define vl_typedefs /* define message structures */ +#include <api/vpe_all_api_h.h> +#undef vl_typedefs + +#define vl_endianfun /* define message structures */ +#include <api/vpe_all_api_h.h> +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) +#define vl_printfun +#include <api/vpe_all_api_h.h> +#undef vl_printfun + +vl_shmem_hdr_t *shmem_hdr; + +typedef struct { + u32 pings_sent; + u32 pings_replied; + volatile u32 signal_received; + + /* convenience */ + unix_shared_memory_queue_t * vl_input_queue; + u32 my_client_index; + svmdb_client_t * svmdb_client; +} test_main_t; + +test_main_t test_main; + +static void vl_api_control_ping_reply_t_handler +(vl_api_control_ping_reply_t * mp) +{ + test_main_t * tm = &test_main; + + fformat(stdout, "control ping reply from pid %d\n", + ntohl (mp->vpe_pid)); + tm->pings_replied++; +} + +void vlib_cli_output (struct vlib_main_t * vm, char * fmt, ...) +{ + clib_warning ("BUG: vlib_cli_output callled..."); +} + +#define foreach_api_msg \ +_(CONTROL_PING_REPLY,control_ping_reply) + +void ping (test_main_t *tm) +{ + vl_api_control_ping_t * mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset(mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_CONTROL_PING); + mp->client_index = tm->my_client_index; + mp->context = 0xdeadbeef; + + vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp); +} + +static void noop_handler (void *notused) { } + +int connect_to_vpe(char *name) +{ + int rv=0; + test_main_t * tm = &test_main; + api_main_t * am = &api_main; + + rv = vl_client_connect_to_vlib("/vpe-api", name, 32); + if (rv < 0) + return rv; + +#define _(N,n) \ + vl_msg_api_set_handlers(VL_API_##N, #n, \ + vl_api_##n##_t_handler, \ + noop_handler, \ + vl_api_##n##_t_endian, \ + vl_api_##n##_t_print, \ + sizeof(vl_api_##n##_t), 1); + foreach_api_msg; +#undef _ + + shmem_hdr = api_main.shmem_hdr; + tm->vl_input_queue = shmem_hdr->vl_input_queue; + tm->my_client_index = am->my_client_index; + return 0; +} + +int disconnect_from_vpe(void) +{ + vl_client_disconnect_from_vlib(); + + return 0; +} + +void signal_handler (int signo) +{ + test_main_t * tm = &test_main; + + tm->signal_received = 1; +} + + +int main (int argc, char **argv) +{ + test_main_t * tm = &test_main; + api_main_t * am = &api_main; + u32 swt_pid = 0; + int connected = 0; + + signal (SIGINT, signal_handler); + + while (1) { + if (tm->signal_received) + break; + + if (am->shmem_hdr) + swt_pid = am->shmem_hdr->vl_pid; + + /* If kill returns 0, the vpe-f process is alive */ + if (kill(swt_pid, 0) == 0) { + /* Try to connect */ + if (connected == 0) { + fformat (stdout, "Connect to VPE-f\n"); + if (connect_to_vpe("test_ha_client") >= 0) { + tm->pings_sent = 0; + tm->pings_replied = 0; + connected = 1; + } else { + fformat(stdout, "Connect failed, sleep and retry...\n"); + sleep(1); + continue; + } + } + tm->pings_sent ++; + ping(tm); + + sleep (1); + + /* havent heard back in 3 seconds, disco / reco */ + if ((tm->pings_replied + 3) <= tm->pings_sent) { + fformat (stdout, "VPE-f pid %d not responding\n", swt_pid); + swt_pid = 0; + disconnect_from_vpe(); + connected = 0; + } + } else { + if (connected) { + fformat (stdout, "VPE-f pid %d died\n", swt_pid); + swt_pid = 0; + disconnect_from_vpe(); + connected = 0; + } + sleep (1); + } + } + + fformat (stdout, "Signal received, graceful exit\n"); + disconnect_from_vpe(); + exit (0); +} |