Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Servers SRVINFO command from EnduroX server (which reports it's status, etc...)
0003  *
0004  * @file cmd_srvinfo.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 
0039 
0040 #include <ndrstandard.h>
0041 #include <ndebug.h>
0042 #include <userlog.h>
0043 #include <ndrxd.h>
0044 #include <ndrxdcmn.h>
0045 #include <atmi_shm.h>
0046 
0047 #include <bridge_int.h>
0048 
0049 #include "cmd_processor.h"
0050 #include "utlist.h"
0051 /*---------------------------Externs------------------------------------*/
0052 /*---------------------------Macros-------------------------------------*/
0053 /*---------------------------Enums--------------------------------------*/
0054 /*---------------------------Typedefs-----------------------------------*/
0055 /*---------------------------Globals------------------------------------*/
0056 /*---------------------------Statics------------------------------------*/
0057 /*---------------------------Prototypes---------------------------------*/
0058 
0059 /**
0060  * Set common start info
0061  * @param p_pm PM to set
0062  * @param srvinfo server info received
0063  */
0064 exprivate void start_start_info(pm_node_t * p_pm, srv_status_t * srvinfo)
0065 {
0066     NDRX_STRCPY_SAFE(p_pm->binary_name_real, 
0067         srvinfo->srvinfo.binary_name_real);
0068 
0069     NDRX_STRCPY_SAFE(p_pm->rqaddress, srvinfo->srvinfo.rqaddress);
0070     p_pm->resid = srvinfo->srvinfo.resid;
0071     p_pm->svpid = srvinfo->srvinfo.svpid; /* save real pid */
0072 
0073     p_pm->state = srvinfo->srvinfo.state;
0074     p_pm->state_changed = SANITY_CNT_START;
0075     /* Assume we inter in running state, thus reset ping timer */
0076     p_pm->pingtimer = SANITY_CNT_START;
0077     p_pm->rspstwatch = SANITY_CNT_START;
0078     p_pm->pingstwatch = SANITY_CNT_IDLE;
0079     p_pm->killreq = EXFALSE;
0080     p_pm->exec_seq_try = 0;  /* Reset counter as we are good */
0081     p_pm->flags = srvinfo->srvinfo.flags; /* save flags */
0082     p_pm->nodeid = srvinfo->srvinfo.nodeid; /* Save node id */
0083     p_pm->procgrp_lp_no = srvinfo->srvinfo.procgrp_lp_no; /**< Reported singleton group... */
0084 }
0085 /**
0086  * Process Server Info request.
0087  * No response required, this is just for info!
0088  * @param args
0089  * @return SUCCEED?
0090  */
0091 expublic int cmd_srvinfo (command_call_t * call, char *data, size_t len, int context)
0092 {
0093     int ret=EXSUCCEED;
0094     srv_status_t * srvinfo = (srv_status_t *)call;
0095     pm_node_t * p_pm;
0096     pm_node_t * p_pm_chk;
0097     pm_pidhash_t *pm_pid;
0098     int i;
0099     int srvid;
0100     /* So what we should do here?
0101      * 1. Mark that service is running.
0102      * 2. Populate server's linked list with advertised services.
0103      *
0104      * We expect to get this message in case if we start up or we re-attach to
0105      * existing runtime where ndrxd where exit dead.
0106      */
0107 
0108     /* refresh the state */
0109     NDRX_LOG(log_debug, "Call from server: %d, state: %d rqaddr: [%s]",
0110                             srvinfo->srvinfo.srvid, srvinfo->srvinfo.state,
0111                             srvinfo->srvinfo.rqaddress);
0112     
0113     srvid=srvinfo->srvinfo.srvid;
0114     if (srvid>=0 && srvid<ndrx_get_G_atmi_env()->max_servers
0115         /* Fix for BSD Bug #129 - seems that in some test cases we might get
0116          * late messages from exiting queue or processes which only now boots from
0117          * previous test case
0118          * thus drop such messages, if PM is not loaded
0119          */
0120         && NULL!=G_process_model_hash)
0121     {
0122         p_pm = G_process_model_hash[srvid];
0123     }
0124     else
0125     {
0126         NDRX_LOG(log_error, "Corrupted server id: %d - ignore request", 
0127                 srvid);
0128         goto out;
0129     }
0130     
0131     if (NULL==p_pm)
0132     {
0133         NDRX_LOG(log_error, "Unknown server id %d - ignore request!", 
0134                         srvinfo->srvinfo.srvid);
0135         goto out;
0136     }
0137     
0138     /* TODO: If server was shutdown, but we got call, then update PID! */
0139     
0140     /* crosscheck PID?  - if we start process in manual mode, then this does not matter!
0141      * better update PID!
0142      * In case if booted from script too, then PID shall be used the one the
0143      * server reports and not the actual one with which server was booted.
0144      */
0145     pm_pid =pid_hash_get(G_process_model_pid_hash, srvinfo->srvinfo.pid);
0146 
0147     if (NULL!=pm_pid)
0148     {
0149         p_pm_chk = pm_pid->p_pm;
0150         if (srvinfo->srvinfo.srvid!=p_pm_chk->srvid)
0151         {
0152             NDRX_LOG(log_error, "Got message from pid=%d, srvid=%d but not "
0153                                 "match for server id %d for same PID in system!!!",
0154                                 srvinfo->srvinfo.pid, srvinfo->srvinfo.srvid, 
0155                                 p_pm_chk->srvid);   
0156             goto out;
0157         }
0158         
0159         /* Check the state of original of current process */
0160         if (NDRXD_PM_STARTING == p_pm_chk->state)
0161         {
0162             NDRX_LOG(log_warn, "Binary was starting up, updating status");
0163             start_start_info(p_pm, srvinfo);
0164         }
0165         else if (NDRXD_PM_RUNNING_OK == p_pm_chk->state)
0166         {
0167             NDRX_LOG(log_warn, "Existing server already runs OK "
0168                     "this is some mistake!");
0169             /* TODO: We could referesh service list! */
0170             goto out;
0171         }
0172         else
0173         {
0174             start_start_info(p_pm, srvinfo);
0175             
0176             /* Bug #501
0177              * we might get here if shutdown was requested for the server
0178              * but it was slow for startup thus sent us infos
0179              * So do not delete any queue it was open, if pids are the
0180              * same
0181              *
0182              * remove *only* if server died
0183              * if pid is the same, the pid was marked requested for
0184              * shutdown
0185              */
0186             if (p_pm->pid != srvinfo->srvinfo.pid)
0187             {
0188                 NDRX_LOG(log_warn, "We assume that this PID is good "
0189                     "one & will remove old one!");
0190 
0191                 remove_startfail_process(p_pm_chk, NULL, NULL);
0192 
0193                 /* reset shared memory! */
0194                 ndrxd_shm_resetsrv(p_pm_chk->srvid);
0195                 /* Now install stuff in pidhash */
0196 
0197                 p_pm->pid = srvinfo->srvinfo.pid;
0198                 add_to_pid_hash(G_process_model_pid_hash, p_pm);
0199             }
0200             else
0201             {
0202                 NDRX_LOG(log_warn, "Seems like shutdown is requested "
0203                         "while server starting up!");
0204             }
0205         }
0206         
0207     }
0208     else
0209     {
0210         /* This could be external process (not started by ndrxd)! - 
0211          * so we register it in PID list */
0212         NDRX_LOG(log_warn, "Seems like server is not started by ndrxd! "
0213                 "The pid %d was not found in PID hash", srvinfo->srvinfo.pid);
0214         
0215         start_start_info(p_pm, srvinfo);
0216 
0217         p_pm->pid = srvinfo->srvinfo.pid;        
0218         p_pm->reqstate = NDRXD_PM_RUNNING_OK;/* If process is now running, 
0219                                       * then assume we want it keep running! */
0220         
0221         add_to_pid_hash(G_process_model_pid_hash, p_pm);
0222     }
0223     
0224     /* Load the list of the services into structures? */
0225     brd_begin_diff();
0226     for (i=0; i<srvinfo->svc_count; i++)
0227     {
0228         /* OK, now populate the stuff stuff, hmm we migth update 
0229          * if there is already entry (if we request this on runtime?!?!)
0230          */
0231         pm_node_svc_t *svc_info = (pm_node_svc_t *)NDRX_MALLOC(sizeof(pm_node_svc_t));
0232         memset((char *)svc_info, 0, sizeof(svc_info));
0233         if (NULL==svc_info)
0234         {
0235             NDRXD_set_error_fmt(NDRXD_EOS, "Failed to allocate pm_node_svc_t(%d)!",
0236                                             sizeof(pm_node_svc_t));
0237             ret=EXFAIL;
0238             goto out;
0239         }
0240 
0241         /* initialize service info sent from server. */
0242         svc_info->svc = srvinfo->svcs[i];
0243         NDRX_LOG(log_debug, "Server [%s] advertises: svc: [%s] func: [%s]",
0244                                 p_pm->binary_name, svc_info->svc.svc_nm, 
0245                 svc_info->svc.fn_nm);
0246         /* Add this to the list */
0247         DL_APPEND(p_pm->svcs, svc_info);
0248         /* add stuff to bridge service hash */
0249         if (EXSUCCEED!=brd_add_svc_to_hash(svc_info->svc.svc_nm))
0250         {
0251             ret=EXFAIL;
0252             goto out;
0253         }
0254     }
0255     
0256     if (srvinfo->srvinfo.flags & SRV_KEY_FLAGS_BRIDGE)
0257     {
0258         NDRX_LOG(log_debug, "Server is bridge - update bridge table");
0259         if (EXSUCCEED!=brd_addupd_bridge(srvinfo))
0260         {
0261             ret=EXFAIL;
0262             goto out;
0263         }
0264     }
0265     brd_end_diff();
0266     /*
0267     p_pm->state = NDRXD_PM_RUNNING_OK;
0268     */
0269     /* TODO: Put server by it self in shm (initialize stats, etc...?) */
0270     
0271 out:
0272     return ret;
0273 }
0274 /* vim: set ts=4 sw=4 et smartindent: */