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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2