(file) Return to ServerProcessOS400.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Service

  1 karl  1.8 //%2006////////////////////////////////////////////////////////////////////////
  2 h.sterling 1.1 //
  3                // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4                // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5                // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6                // IBM Corp.; EMC Corporation, The Open Group.
  7                // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8                // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9                // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10                // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl       1.8 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12                // EMC Corporation; Symantec Corporation; The Open Group.
 13 h.sterling 1.1 //
 14                // Permission is hereby granted, free of charge, to any person obtaining a copy
 15                // of this software and associated documentation files (the "Software"), to
 16                // deal in the Software without restriction, including without limitation the
 17                // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18                // sell copies of the Software, and to permit persons to whom the Software is
 19                // furnished to do so, subject to the following conditions:
 20                // 
 21                // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22                // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23                // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24                // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25                // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26                // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27                // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28                // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29                //
 30                //==============================================================================
 31                //
 32                //%/////////////////////////////////////////////////////////////////////////////
 33                
 34 h.sterling 1.1 #include <sys/types.h>
 35                #include <sys/stat.h>
 36                #include <fcntl.h>
 37                #include <unistd.h>
 38 chuck      1.3 #include <sys/wait.h>
 39 h.sterling 1.1 #include <Pegasus/Common/Config.h>
 40                #include <Pegasus/Common/String.h>
 41                #include <Pegasus/Common/Logger.h>
 42 chuck      1.3 #include <Pegasus/Config/ConfigManager.h>
 43 h.sterling 1.1 #include "OS400ConvertChar.h"
 44 chuck      1.3 #include "SSLWrapperOS400.h"
 45                #include "OS400SystemState.h"
 46 lucier     1.4 #include "CIMRepositoryUpdate400.h"  // upgrade utility
 47 h.sterling 1.1 #include <Pegasus/Common/MessageLoader.h> //l10n
 48                #include <except.h>
 49                
 50                #include <stdio.h>
 51                #include "qycmutiltyUtility.H"
 52                #include "qycmjobjobJob.H"
 53                #include "qycmmsgclsMessage.H"
 54                #include "licall.h"        // EPTCALL macros.
 55                
 56                // Needed for QWTCHGJB API
 57                #include <qwtchgjb.cleinc>
 58                #include "qushdler.H"
 59                
 60                //Needed for SQL APIs
 61                #include "sqlcli.h"
 62                
 63                // Structure need for the CHGJOB(QWTCHGJB) API
 64                typedef struct jobChangeInfo
 65                {
 66                   Qus_Job_Change_Information_t  fieldNum;
 67                   Qus_JOBC0100_t                format;
 68 h.sterling 1.1    char                          data[31];
 69                } jobChangeInfo_t;
 70                
 71                // Errorcode for system API calls
 72                Qus_EC_t errorCode;
 73                
 74                PEGASUS_USING_PEGASUS;
 75                PEGASUS_USING_STD;
 76                
 77                
 78                //constructor
 79                ServerProcess::ServerProcess() {}
 80                
 81                //destructor
 82                ServerProcess::~ServerProcess() {}
 83                
 84                // no-ops
 85                void ServerProcess::notify_parent(int id) {}
 86                void ServerProcess::cimserver_set_process(void* p) {}
 87                long ServerProcess::get_server_pid(void) { return 0; }
 88 h.sterling 1.2 void ServerProcess::set_parent_pid(int pid) {}
 89 h.sterling 1.1 int ServerProcess::get_proc(int pid) { return 0; }
 90                int ServerProcess::cimserver_wait(void) { return 1; }
 91                String ServerProcess::getHome(void) { return String::EMPTY; }
 92                
 93                ///////////////////////////////////////////////////////////////////////
 94                // cimserver_fork()
 95                //
 96                // The iSeries qycmctlcimCimomServer.C (QYCMCTLCIM program) code has
 97                // already checked that the CIMOM server is not already running prior
 98                // to calling the CIMOM server (QYCMCIMOM) and telling it to start itself.
 99                // Therefore, no check is made in this method to ensure the CIMOM server
100                // is not already running.
101                //
102                // Note: This code was written because fork( ) is not supported on OS/400.
103                ///////////////////////////////////////////////////////////////////////
104                int ServerProcess::cimserver_fork(void) 
105                {
106 lucier     1.4   // First migrate the server configuration settings into the planned file.
107                  CIMRepositoryUpdate400 obj;
108                  obj.preserveConfigSettings();
109                
110 lucier     1.5   // TODO:  This is here for now until we can move it into initialize.  Right now it doesn't run because qycmsetupr won't work in a multi-threaded environment.  See issue #AD2
111                  obj.doIt();
112                
113 h.sterling 1.1 #pragma convert(37)
114                  char rc5[3] = "05"; // rc5 means the CIMOM Server failed to start
115                  char cppServ[10] = "QYCMCIMOM";
116                  ycmJob cppJob(YCMJOB_SRVNAME_10, YCMJOB_SRVUSER_10); 
117                
118                  // Submit the server job (QYCMCIMOM).  The job is submitted with the
119                  // daemon=false parameter to avoid an infinite loop of jobs being
120                  // submitted by this code!
121                  if (YCMJOB_SUBMIT_FAILED == cppJob.submit(YCMJOB_SRVR_PGM,  
122                                        YCMJOB_QSYS_LIB,
123                                        "daemon=false",
124                                        YCMJOB_JOBD,
125                                        YCMJOB_QSYS_LIB,
126                                        YCMJOB_CCSID_37,
127                                        YCMJOB_THREAD_YES))
128                  {  // QYCMCIMOM Server Failed on Submit Job
129                #pragma convert(0)
130                
131                      //l10n
132                      //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
133                         //"cimserver_os400::cimserver_fork() - SBMJOB failed to start the QYCMCIMOM server program!!");
134 h.sterling 1.1     Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
135                                "src.Server.cimserver_os400.FAILED_TO_START_SERVER",
136                                "$0 failed to start the $1 server program!!",
137                                "cimserver_os400::cimserver_fork() - SBMJOB",
138                                "QYCMCIMOM");
139                
140                
141                     char chData[sizeof(rc5)+sizeof(cppServ)];
142                     strcpy((char *)&chData,rc5);
143                     strcat(chData,cppServ);
144                
145                #pragma convert(37)
146                     ycmMessage message("CPDDF80",
147                                        chData,
148                            strlen(chData),
149                                        "cimserver_os400::cimserver_fork()",
150                                        ycmCTLCIMID,
151                            utf8);
152                     message.joblogIt(UserError,ycmMessage::Diagnostic);
153                #pragma convert(0)
154                
155 h.sterling 1.1      // save the job log
156                     system ("QSYS/CHGJOB JOB(*) LOG(4 00 *SECLVL)");
157                
158                
159                     return(-1);    // -1 indicates to QYCMCIMOM that the server failed to start
160                  }
161                
162                  // The QYCMCIMOM job was submitted with daemon=false.  This job can now exit.
163                  // This is similiar to what the unix version of this code does - the parent exits
164                  // after the fork( )
165                  return(0);
166                }
167                
168                
169                ////////////////////////////////////////////////////
170                //  CancelHandler
171                ////////////////////////////////////////////////////
172                void CancelHandler (_CNL_Hndlr_Parms_T *cancelParms)
173                {  // make sure a job log gets saved too
174                   system ("QSYS/CHGJOB JOB(*) LOG(4 00 *SECLVL)");
175                }
176 h.sterling 1.1 
177                
178                ////////////////////////////////////////////////////
179                // iSeries-specific function to initialize the server.
180                // Does the following:
181                //    -- Sets the server type to QIBM_CIMOM
182                //       so that iNavigator can start/stop it.
183                //    -- Swaps the job user to QSYS. 
184                //    -- Changes the authority of QYCMJOBD
185 lucier     1.5 //    -- Calls the upgrade utility
186 h.sterling 1.1 ////////////////////////////////////////////////////
187                int ServerProcess::cimserver_initialize(void)
188                {
189                    SQLHENV    henv; // SQL environment variable
190                    long       attr; // SQL attribute to be set
191                
192                   // setup cancel handler to make sure job log gets saved if we exit abnormally
193                   // TODO:  this is currently commented out because it causes build errors -
194                   //        it compiles just fine though.  Hopefully this problem will be fixed
195                   //        (it's a known problem) and we can uncomment this #pragma. 
196                //   #pragma cancel_handler (CancelHandler, NULL)
197                    try {
198                
199                #pragma convert(37)
200                   //////////////////////////////////////////
201                   // Change Job API call
202                   // Change the server type to QICM_CIMOM
203                   ////////////////////////////////////////// 
204                   jobChangeInfo_t chg = {1,
205                                          46,
206                                          1911,
207 h.sterling 1.1                           'C',
208                                          0X40,0X40,0X40,30,
209                                          "QIBM_CIMOM                    ",
210                                         };
211                
212                   // Initialize the error code structure to signal exceptions
213                   errorCode.Bytes_Provided = 0;
214                
215                   // Call CHGJOB API with Server Type field
216                   EPTCALL(QWTCHGJB, ("*                         ",
217                            "                ",
218                            "JOBC0200",
219                            &chg,
220                            &errorCode), OFF, OFF);
221                #pragma convert(0)
222                
223                   ////////////////////////////////////////////////////
224                   // Change authority to the qypsjobd job description
225                   //////////////////////////////////////////////////// 
226                   system("QSYS/GRTOBJAUT OBJ(QSYS/QYCMJOBD) OBJTYPE(*JOBD) USER(*PUBLIC) AUT(*EXCLUDE)");
227                
228 h.sterling 1.1    SQLAllocEnv(&henv);  // Allocating SQL environment variable
229                   attr = SQL_TRUE;     // Set SQL attribute to true
230                   
231                   // Set the SQL server mode to true.
232                   // This will allow multiple connections to the same data source.
233                   SQLSetEnvAttr(henv,SQL_ATTR_SERVER_MODE, &attr,0);
234 chuck      1.3 
235                   //--------------------------------------------------
236                   // Create server SSL certificate and private key
237                   // if they do not already exist.
238                   //--------------------------------------------------
239                
240 sushma.fernandes 1.10    // Check if SSL is enabled on the wbem-https port
241 chuck            1.3     ConfigManager * configManager = ConfigManager::getInstance();
242 kumpf            1.9     Boolean enableHttpsConnection = ConfigManager::parseBooleanValue(
243                               configManager->getCurrentValue("enableHttpsConnection"));
244 sushma.fernandes 1.10    if (enableHttpsConnection) 
245 chuck            1.3     {
246                              // Initialize the OS400 OpenSSL wrapper.
247                              // This checks if the OpenSSL LPO is installed.
248                              // It also activates the OpenSSL *SRVPGM and gets exports.
249                              SSL_OS400_Init();
250                       
251                              // Create the certificate if needed
252                              // Get the location of the certificate
253                              String certPath;
254                              certPath = ConfigManager::getHomedPath(
255                                   configManager->getCurrentValue("sslCertificateFilePath"));
256                       
257                              // Get the location of the private key
258                              String keyPath;
259                              keyPath = ConfigManager::getHomedPath(
260                                   configManager->getCurrentValue("sslKeyFilePath"));
261                       
262                              SSL_CreateCert_OS400(keyPath, certPath);
263                          }
264                         }
265                         catch (Exception & e)
266 chuck            1.3    {
267                             //l10n
268                             Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
269                       		  e.getMessage()); 
270                             return(-1);
271                         }
272 h.sterling       1.1    catch (...)
273                         {
274                             //l10n
275                             //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
276                                 //"cimerver_os400::cimserver_os400_setup() - caught unknown exception\n");
277                               Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
278                                   "src.Server.cimserver_os400.CAUGHT_UNKNOWN_EXCEPTION",
279                                   "$0 caught unknown exception\n",
280                                   "cimerver_os400::cimserver_os400_setup() -");
281                       
282                             return(-1);
283                         }
284 lucier           1.4    
285 lucier           1.5  // TODO:  add this back in when we fix the problem with setupr not working in a multi-threaded environment.
286 lucier           1.4    // Call into the upgrade utility.  This will perform any necessary upgrade step that need to be done.  The upgrade program keys off of marker files which are created on install.  This means that in most cases, nothing will be done unless the server is starting for the first time after an install.
287 lucier           1.5  //  CIMRepositoryUpdate400 obj;
288                       //  obj.doIt();
289 h.sterling       1.1  
290                          // TODO:  this is currently commented out because it causes build errors -
291                          //        it compiles just fine though.  Hopefully this problem will be fixed
292                          //        (it's a known problem) and we can uncomment this #pragma. 
293                       //  #pragma disable_handler
294                       
295                           return(0);
296                       }
297                       
298                       ///////////////////////////////////////////////////////////////////////
299                       // cimserver_kill()
300                       //
301                       // The iSeries qycmctlcimCimomServer.C (QYCMCTLCIM program) code has
302                       // already checked that the CIMOM server is already running prior to
303                       // calling the CIMOM server (QYCMCIMOM) and telling it to shutdown.
304                       // However, a check is still made in this method because we have to
305                       // find the job number in order to kill the job.
306                       //
307                       // For iSeries, this method is called regardless of whether we took
308                       // errors trying to connect to the server - if the CIMOM server job
309                       // is anywhere on the system, in any state, this method will find it
310 h.sterling       1.1  // and kill it dead!!
311                       //
312                       // NEVER call this method unless the server is unable to be shut down
313                       // gracefully.
314                       ///////////////////////////////////////////////////////////////////////
315                       int ServerProcess::cimserver_kill(int id)
316                       {  // Need to kill the server
317                       #pragma convert(37)
318                         char rc2[3] = "02"; // CIMOM server failed to end
319                         char cppServ[10] = "QYCMCIMOM";
320                       
321                         // Construct a ycmJob object
322                         ycmJob cppJob(YCMJOB_SRVNAME_10, YCMJOB_SRVUSER_10);
323                         // Find the QYCMCIMOM job
324                         char cppStatus  = cppJob.find(YCMJOB_ALL_NUMBERS);
325                       
326                         if (cppStatus == YCMJOB_FOUND)       // CIMOM Server is Running
327                         {
328                           if (cppJob.end((char *)cppJob.getNumber().c_str(), 'C', 30) == YCMJOB_END_FAILED)
329                           {
330                       
331 h.sterling       1.1        char chData[sizeof(rc2)+sizeof(cppServ)];
332                             strcpy((char *)&chData,rc2);
333                             strcat(chData,cppServ);
334                       
335                             ycmMessage message("CPDDF81",
336                                                chData,
337                                    strlen(chData),
338                                                "cimserver_os400::cimserver_kill()",
339                                                ycmCTLCIMID,
340                                    utf8);
341                             message.joblogIt(UserError,ycmMessage::Diagnostic);
342                       
343                       #pragma convert(0)
344                       
345                             //l10n
346                             //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
347                                 //"cimserver_os400::cimserver_kill - FAILED to end the QYCMCIMOM job!!");
348                           Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
349                                   "src.Server.cimserver_os400.FAILED_TO_END_JOB",
350                                   "$0 FAILED to end the $1 job!!",
351                                   "cimserver_os400::cimserver_kill -",
352 h.sterling       1.1              "QYCMCIMOM");
353                       
354                       
355                             return -1; // Note: this return code is ignored by the CIMOM server.
356                           }
357                         }
358                         // The case of the job not found is already handled in QYCMCTLCIM program
359                           return(0);
360                       }
361                       
362                       ////////////////////////////////////////////////////
363                       //  Checks if the QYCMCIMOM server job is running.
364                       ////////////////////////////////////////////////////
365                       Boolean ServerProcess::isCIMServerRunning(void)
366                       {
367                       #pragma convert(37)
368                         // Construct a ycmJob object
369                         ycmJob cppJob(YCMJOB_SRVNAME_10, YCMJOB_SRVUSER_10);
370                       
371                         // Find the QYCMCIMOM job
372                         char cppStatus  = cppJob.find(YCMJOB_ALL_NUMBERS);
373 h.sterling       1.1  
374                         if (cppStatus == YCMJOB_FOUND)       // CIMOM Server is Running
375                         {
376                             return true; 
377                         }
378                       
379                         return false;
380                       #pragma convert(0)
381                       }
382                       
383                       ////////////////////////////////////////////////////
384                       //  Setup a fifo for process communication
385                       ////////////////////////////////////////////////////
386                       int init_fifo(const char * fifo_name){
387                           int fifo = -1;
388                           struct stat FIFO_STAT;
389                       
390                           // Need to convert the fifo name to ebcdic because
391                           // that is what stat and open want.   
392                           char tmp[256];
393                           strcpy(tmp, fifo_name);
394 h.sterling       1.1      AtoE(tmp);
395                           
396                           int stat_rc = stat( tmp, &FIFO_STAT );
397                       
398                           // check if the FIFO already exists
399                           if( S_ISFIFO( FIFO_STAT.st_mode ) ){
400                           // prep FIFO, on this end we only want to write to it,
401                           // set its I/O mode to not block on any reads
402                           fifo = open(tmp, O_RDWR | O_NONBLOCK);
403                           }
404                           return fifo;
405                       }
406                        
407                        
408                       ////////////////////////////////////////////////////
409                       //  Sends return code back to caller before exiting...
410                       ////////////////////////////////////////////////////
411                       void ServerProcess::cimserver_exitRC(int rc){
412                           int fifo = init_fifo(QYCMSSERV_FIFO);
413                           
414                           if( fifo != -1 ){
415 h.sterling       1.1      char rc_tmp[3];
416                           memset(rc_tmp, 0, 3);
417                           sprintf(rc_tmp,"%d",rc);
418                           AtoE(rc_tmp);  // qycmctlcim wants ebcdic
419                           write(fifo,rc_tmp,strlen(rc_tmp));
420                           }
421                       
422                           exit(rc);    
423                       }
424                       
425                       ////////////////////////////////////////////////////
426                       // Platform specific run
427                       ////////////////////////////////////////////////////
428 kumpf            1.7  int ServerProcess::platform_run(
429                           int argc,
430                           char** argv,
431                           Boolean shutdownOption,
432                           Boolean debugOutputOption)
433 h.sterling       1.1  {
434 kumpf            1.7      return cimserver_run(argc, argv, shutdownOption, debugOutputOption);
435 h.sterling       1.1  }
436                       

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2