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 // 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 kumpf 1.7 int ServerProcess::platform_run(
441 int argc,
442 char** argv,
443 Boolean shutdownOption,
444 Boolean debugOutputOption)
|
445 h.sterling 1.1 {
|
446 kumpf 1.7 return cimserver_run(argc, argv, shutdownOption, debugOutputOption);
|
447 h.sterling 1.1 }
448
|