Commit 66fe672c authored by Adam Wujek's avatar Adam Wujek 💬

userspace/snmpd: allow snmpd to start without HAL and PPSI

SNMPd will try to connect to HAL's and PPSI's shmem at startup. If HAL or PPSI
is not started SNMPd would continue instead of exiting. Later when data from
shmem is needed SNMPd will try to open shmem again. By this it would be
possible to figure out what is happening on switch when HAL, PPSI or RTUd
failed to start.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent fbbb4154
......@@ -17,28 +17,29 @@ int *ppsi_ppi_nlinks;
/* RTUd */
struct wrs_shm_head *rtud_head;
int shmem_open_hald;
int shmem_open_ppsi;
int shmem_open_rtud;
static void init_shm_hal(void)
static int init_shm_hald(void)
{
int ret;
int n_wait = 0;
static int n_wait = 0;
while ((ret = wrs_shm_get_and_check(wrs_shm_hal, &hal_head)) != 0) {
n_wait++;
if (n_wait > 10) {
/* timeout! */
if (ret == 1) {
snmp_log(LOG_ERR, "Unable to open HAL's "
"shmem!\n");
}
if (ret == 2) {
snmp_log(LOG_ERR, "Unable to read HAL's "
"version!\n");
}
exit(-1);
ret = wrs_shm_get_and_check(wrs_shm_hal, &hal_head);
n_wait++;
/* start printing error after 5 messages */
if (n_wait > 5) {
if (ret == 1) {
snmp_log(LOG_ERR, "Unable to open HAL's shmem!\n");
}
if (ret == 2) {
snmp_log(LOG_ERR, "Unable to read HAL's version!\n");
}
sleep(1);
}
if (ret) {
/* return if error while opening shmem */
return ret;
}
/* check hal's shm version */
......@@ -46,7 +47,7 @@ static void init_shm_hal(void)
snmp_log(LOG_ERR, "unknown hal's shm version %i "
"(known is %i)\n", hal_head->version,
HAL_SHMEM_VERSION);
exit(-1);
return 3;
}
hal_shmem = (void *)hal_head + hal_head->data_off;
......@@ -56,7 +57,7 @@ static void init_shm_hal(void)
snmp_log(LOG_ERR, "Too many ports reported by HAL. "
"%d vs %d supported\n",
hal_nports_local, WRS_N_PORTS);
exit(-1);
return 3;
}
/* Even after HAL restart, HAL will place structures at the same
* addresses. No need to re-dereference pointer at each read. */
......@@ -64,52 +65,58 @@ static void init_shm_hal(void)
if (!hal_ports) {
snmp_log(LOG_ERR, "Unalbe to follow hal_ports pointer in HAL's"
" shmem");
exit(-1);
return 3;
}
/* everything is ok */
return 0;
}
static void init_shm_ppsi(void)
static int init_shm_ppsi(void)
{
int ret;
int n_wait = 0;
while ((ret = wrs_shm_get_and_check(wrs_shm_ptp, &ppsi_head)) != 0) {
n_wait++;
if (n_wait > 10) {
/* timeout! */
if (ret == 1) {
snmp_log(LOG_ERR, "Unable to open shm for PPSI!\n");
}
if (ret == 2) {
snmp_log(LOG_ERR, "Unable to read PPSI's version!\n");
}
exit(-1);
ret = wrs_shm_get_and_check(wrs_shm_ptp, &ppsi_head);
n_wait++;
/* start printing error after 5 messages */
if (n_wait > 5) {
/* timeout! */
if (ret == 1) {
snmp_log(LOG_ERR, "Unable to open shm for PPSI!\n");
}
sleep(1);
if (ret == 2) {
snmp_log(LOG_ERR, "Unable to read PPSI's version!\n");
}
}
if (ret) {
/* return if error while opening shmem */
return ret;
}
/* check ppsi's shm version */
if (ppsi_head->version != WRS_PPSI_SHMEM_VERSION) {
snmp_log(LOG_ERR, "unknown PPSI's shm version %i "
snmp_log(LOG_ERR, "unknown PPSI's shm version %i "
"(known is %i)\n",
ppsi_head->version, WRS_PPSI_SHMEM_VERSION);
exit(-1);
return 3;
}
ppg = (void *)ppsi_head + ppsi_head->data_off;
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->global_ext_data);
if (!ppsi_servo) {
snmp_log(LOG_ERR, "Cannot follow ppsi_servo in shmem.\n");
exit(-1);
return 4;
}
ppsi_ppi = wrs_shm_follow(ppsi_head, ppg->pp_instances);
if (!ppsi_ppi) {
snmp_log(LOG_ERR, "Cannot follow ppsi_ppi in shmem.\n");
exit(-1);
return 5;
}
/* use pointer instead of copying */
ppsi_ppi_nlinks = &(ppg->nlinks);
return 0;
}
static int init_shm_rtud(void)
......@@ -145,6 +152,24 @@ static int init_shm_rtud(void)
return 0;
}
int shmem_ready_hald(void)
{
if (shmem_open_hald) {
return 1;
}
shmem_open_hald = !init_shm_hald();
return shmem_open_hald;
}
int shmem_ready_ppsi(void)
{
if (shmem_open_ppsi) {
return 1;
}
shmem_open_ppsi = !init_shm_ppsi();
return shmem_open_ppsi;
}
int shmem_ready_rtud(void)
{
if (shmem_open_rtud) {
......@@ -157,9 +182,23 @@ int shmem_ready_rtud(void)
void init_shm(void){
int i;
init_shm_hal();
init_shm_ppsi();
for (i = 0; i < 10; i++) {
for (i = 0; i < 1; i++) {
if (shmem_ready_hald()) {
/* shmem opened successfully */
break;
}
/* wait 1 second before another try */
sleep(1);
}
for (i = 0; i < 1; i++) {
if (shmem_ready_ppsi()) {
/* shmem opened successfully */
break;
}
/* wait 1 second before another try */
sleep(1);
}
for (i = 0; i < 1; i++) {
if (shmem_ready_rtud()) {
/* shmem opened successfully */
break;
......
......@@ -23,5 +23,8 @@ extern int *ppsi_ppi_nlinks;
struct wrs_shm_head *rtud_head;
void init_shm();
int shmem_ready_hald(void);
int shmem_ready_ppsi(void);
int shmem_ready_rtud(void);
#endif /* WRS_SNMP_SHMEM_H */
......@@ -30,10 +30,11 @@ time_t wrsPortStatusTable_data_fill(unsigned int *n_rows)
static time_t time_update;
time_t time_cur;
char *ppsi_iface_name;
static int n_rows_local = 0;
/* number of rows does not change for wrsPortStatusTable */
if (n_rows)
*n_rows = WRS_N_PORTS;
*n_rows = n_rows_local;
time_cur = time(NULL);
if (time_update
......@@ -43,9 +44,23 @@ time_t wrsPortStatusTable_data_fill(unsigned int *n_rows)
}
time_update = time_cur;
/* read data, with the sequential lock to have all data consistent */
struct hal_port_state *port_state;
memset(wrsPortStatusTable_array, 0, sizeof(wrsPortStatusTable_array));
/* check whether shmem is available */
if (!shmem_ready_hald()) {
/* there was an update, return current time */
snmp_log(LOG_ERR, "%s: Unable to read HAL's shmem\n", __func__);
n_rows_local = 0;
return time_cur;
} else {
n_rows_local = WRS_N_PORTS;
}
if (n_rows)
*n_rows = n_rows_local;
/* read data, with the sequential lock to have all data consistent */
while (1) {
ii = wrs_shm_seqbegin(hal_head);
for (i = 0; i < hal_nports_local; ++i) {
......@@ -124,6 +139,14 @@ time_t wrsPortStatusTable_data_fill(unsigned int *n_rows)
}
retries = 0;
/* check whether shmem is available */
if (!shmem_ready_ppsi()) {
/* there was an update, return current time */
snmp_log(LOG_ERR, "%s: Unable to read PPSI's shmem\n",
__func__);
return time_cur;
}
/* fill ptp_tx_count and ptp_tx_count
* ptp_tx_count and ptp_tx_count statistics in PPSI are collected per
* ppi instance. Since there can be more than one instance per physical
......
......@@ -46,10 +46,11 @@ time_t wrsPtpDataTable_data_fill(unsigned int *n_rows)
unsigned retries = 0;
static time_t time_update;
time_t time_cur;
static int n_rows_local = 0;
/* number of rows does not change for wrsPortStatusTable */
if (n_rows)
*n_rows = WRS_MAX_N_SERVO_INSTANCES;
*n_rows = n_rows_local;
time_cur = time(NULL);
if (time_update
......@@ -60,6 +61,19 @@ time_t wrsPtpDataTable_data_fill(unsigned int *n_rows)
time_update = time_cur;
memset(&wrsPtpDataTable_array, 0, sizeof(wrsPtpDataTable_array));
/* check whether shmem is available */
if (!shmem_ready_ppsi()) {
snmp_log(LOG_ERR, "%s: Unable to read PPSI's shmem\n", __func__);
n_rows_local = 0;
return time_update;
} else {
n_rows_local = WRS_MAX_N_SERVO_INSTANCES;
}
if (n_rows)
*n_rows = n_rows_local;
/* assume that there is only one servo, will change when switchover is
* implemented */
while (1) {
......
......@@ -53,12 +53,20 @@ time_t wrsStartCnt_data_fill(void){
memset(&wrsStartCnt_s, 0, sizeof(wrsStartCnt_s));
/* get start counters from shmem's */
wrsStartCnt_s.wrsStartCntHAL = hal_head->pidsequence;
wrsStartCnt_s.wrsStartCntPTP = ppsi_head->pidsequence;
if (shmem_ready_hald()) {
wrsStartCnt_s.wrsStartCntHAL = hal_head->pidsequence;
} else {
snmp_log(LOG_ERR, "%s: Unable to read HAL's shmem\n", __func__);
}
if (shmem_ready_ppsi()) {
wrsStartCnt_s.wrsStartCntPTP = ppsi_head->pidsequence;
} else {
snmp_log(LOG_ERR, "%s: Unable to read PPSI's shmem\n", __func__);
}
if (shmem_ready_rtud()) {
wrsStartCnt_s.wrsStartCntRTUd = rtud_head->pidsequence;
} else {
snmp_log(LOG_ERR, "Unable to read rtu's shmem\n");
snmp_log(LOG_ERR, "%s: Unable to read rtu's shmem\n", __func__);
}
read_start_count(START_CNT_SSHD, &wrsStartCnt_s.wrsStartCntSshd);
......
......@@ -56,6 +56,12 @@ time_t wrsTemperature_data_fill(void)
first_run = 0;
}
if (!shmem_ready_hald()) {
/* Unable to open shmem, return current time */
snmp_log(LOG_ERR, "%s: Unable to read HAL's shmem\n", __func__);
return time_update;
}
while (1) {
ii = wrs_shm_seqbegin(hal_head);
......
......@@ -175,36 +175,40 @@ time_t wrsTimingStatus_data_fill(void)
* mode. Don't care about non-wr and auto ports.
*/
p_a = wrsPortStatusTable_array;
wrsTimingStatus_s.wrsSlaveLinksStatus = WRS_SLAVE_LINK_STATUS_OK;
for (i = 0; i < port_status_nrows; i++) {
/* warning N/A */
if (/*hal_shmem->s->wrsSpllMode == 0
|| */p_a[i].port_mode == 0
|| p_a[i].link_up == 0){
wrsTimingStatus_s.wrsSlaveLinksStatus =
WRS_SLAVE_LINK_STATUS_WARNING_NA;
}
/* error when slave port is down when switch is in slave mode
*/
if (hal_shmem->hal_mode == HAL_TIMING_MODE_BC
&& (p_a[i].port_mode == WRS_PORT_STATUS_CONFIGURED_MODE_SLAVE)
&& (p_a[i].link_up == WRS_PORT_STATUS_LINK_DOWN)) {
wrsTimingStatus_s.wrsSlaveLinksStatus =
WRS_SLAVE_LINK_STATUS_ERROR;
snmp_log(LOG_ERR, "SNMP: wrsSlaveLinksStatus (slave) "
"failed for port %d\n", i);
}
/* error when slave port is up when switch is in master or
* grandmaster mode */
if (((hal_shmem->hal_mode == HAL_TIMING_MODE_GRAND_MASTER) || (hal_shmem->hal_mode == HAL_TIMING_MODE_FREE_MASTER))
&& (p_a[i].port_mode == WRS_PORT_STATUS_CONFIGURED_MODE_SLAVE)
&& (p_a[i].link_up == WRS_PORT_STATUS_LINK_UP)) {
wrsTimingStatus_s.wrsSlaveLinksStatus =
WRS_SLAVE_LINK_STATUS_ERROR;
snmp_log(LOG_ERR, "SNMP: wrsSlaveLinksStatus (master) "
"failed for port %d\n", i);
/* check whether hal_shmem is available */
if (shmem_ready_hald()) {
wrsTimingStatus_s.wrsSlaveLinksStatus = WRS_SLAVE_LINK_STATUS_OK;
for (i = 0; i < port_status_nrows; i++) {
/* warning N/A */
if (/*hal_shmem->s->wrsSpllMode == 0
|| */p_a[i].port_mode == 0
|| p_a[i].link_up == 0){
wrsTimingStatus_s.wrsSlaveLinksStatus =
WRS_SLAVE_LINK_STATUS_WARNING_NA;
}
/* error when slave port is down when switch is in slave mode
*/
if (hal_shmem->hal_mode == HAL_TIMING_MODE_BC
&& (p_a[i].port_mode == WRS_PORT_STATUS_CONFIGURED_MODE_SLAVE)
&& (p_a[i].link_up == WRS_PORT_STATUS_LINK_DOWN)) {
wrsTimingStatus_s.wrsSlaveLinksStatus =
WRS_SLAVE_LINK_STATUS_ERROR;
snmp_log(LOG_ERR, "SNMP: wrsSlaveLinksStatus (slave) "
"failed for port %d\n", i);
}
/* error when slave port is up when switch is in master or
* grandmaster mode */
if (((hal_shmem->hal_mode == HAL_TIMING_MODE_GRAND_MASTER) || (hal_shmem->hal_mode == HAL_TIMING_MODE_FREE_MASTER))
&& (p_a[i].port_mode == WRS_PORT_STATUS_CONFIGURED_MODE_SLAVE)
&& (p_a[i].link_up == WRS_PORT_STATUS_LINK_UP)) {
wrsTimingStatus_s.wrsSlaveLinksStatus =
WRS_SLAVE_LINK_STATUS_ERROR;
snmp_log(LOG_ERR, "SNMP: wrsSlaveLinksStatus (master) "
"failed for port %d\n", i);
}
}
}
/*********************************************************************\
|************************ wrsPTPFramesFlowing ************************|
\*********************************************************************/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment