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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2