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