1 r.kieninger 1.1 //%2006////////////////////////////////////////////////////////////////////////
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 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
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 r.kieninger 1.1 // 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
35 /////////////////////////////////////////////////////////////////////////////
36 // ConsoleManager
37 /////////////////////////////////////////////////////////////////////////////
38
39 #include <Pegasus/Common/Constants.h>
40 #include <Pegasus/Common/Tracer.h>
41 #include <Pegasus/Common/Logger.h>
42 #include <Pegasus/Common/PegasusVersion.h>
43 r.kieninger 1.1 #include <Pegasus/Common/FileSystem.h>
|
44 kumpf 1.3 #include <Pegasus/Common/AuditLogger.h>
|
45 r.kieninger 1.1 #include <Pegasus/Config/ConfigManager.h>
46
47 #include <sys/__messag.h>
48
49 #include "ConsoleManager_zOS.h"
50 #include "CIMServer.h"
51
52 PEGASUS_NAMESPACE_BEGIN
53
54
55 #define ZOSCONSOLEMANAGER_TOKEN_APPL "CONFIG,"
56 #define ZOSCONSOLEMANAGER_TOKEN_PLANNED "PLANNED"
57
58
59 char* ZOSConsoleManager::skipBlanks( char* commandPtr)
60 {
61 if (commandPtr != NULL)
62 {
63 while (*commandPtr == ' ')
64 {
65 commandPtr++;
66 r.kieninger 1.1 }
67 }
68
69 return commandPtr;
70 }
71
72 void ZOSConsoleManager::stripTrailingBlanks( char* token )
73 {
74 if (token != NULL)
75 {
76 int len = strlen(token)-1;
77
78 while ((len >= 0) && (token[len] == ' '))
79 {
80 token[len] = '\0';
81 len--;
82 }
83 }
84
85 return;
86 }
87 r.kieninger 1.1
88 void ZOSConsoleManager::issueSyntaxError(const char* command)
89 {
|
90 thilo.boehm 1.4 PEG_METHOD_ENTER(TRC_SERVER,
91 "ZOSConsoleManager::issueSyntaxError");
|
92 r.kieninger 1.1 Logger::put_l(
93 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
94 "Server.ConsoleManager_zOS.CON_SYNTAX_ERR.PEGASUS_OS_ZOS",
95 "CIM MODIFY COMMAND REJECTED DUE TO SYNTAX ERROR");
96 Logger::put_l(
97 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
98 "Server.ConsoleManager_zOS.CON_MODIFY_SYNTAX.PEGASUS_OS_ZOS",
99 "Syntax is: MODIFY CFZCIM,APPL=CONFIG,<name>=<value>[,PLANNED]");
100
101 PEG_METHOD_EXIT();
102 return;
103 }
104
105
106 void ZOSConsoleManager::updateConfiguration( const String& configProperty,
107 const String& propertyValue,
108 Boolean currentValueIsNull,
109 Boolean planned)
110 {
|
111 thilo.boehm 1.4 PEG_METHOD_ENTER(TRC_SERVER,
112 "ZOSConsoleManager::updateConfiguration");
|
113 r.kieninger 1.1
114 String preValue;
115 String currentValue;
116
117 try
118 {
119 ConfigManager* _configManager = ConfigManager::getInstance();
120
121 preValue = _configManager->getCurrentValue(configProperty);
122
123 if (!planned)
124 {
125 //
126 // Update the current value
127 //
128 if ( !_configManager->updateCurrentValue(configProperty,
129 propertyValue,
130 currentValueIsNull) )
131 {
132 Logger::put_l(
133 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
134 r.kieninger 1.1 "Server.ConsoleManager_zOS."
135 "CON_MODIFY_FAILED.PEGASUS_OS_ZOS",
136 "Failed to update CONFIG value.");
137 }
138 else
139 {
140 Logger::put_l(
141 Logger::STANDARD_LOG, System::CIMSERVER,
142 Logger::INFORMATION,
143 "Server.ConsoleManager_zOS."
144 "CON_MODIFY_UPDATED.PEGASUS_OS_ZOS",
145 "Updated current value for $0 to $1",
146 configProperty, propertyValue);
147 }
148 }
149 else
150 {
151 //
152 // Update the planned value
153 //
154 if ( !_configManager->updatePlannedValue(configProperty,
155 r.kieninger 1.1 propertyValue,
156 currentValueIsNull) )
157 {
158 Logger::put_l(
159 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
160 "Server.ConsoleManager_zOS."
161 "CON_MODIFY_FAILED.PEGASUS_OS_ZOS",
162 "Failed to update CONFIG value.");
163 }
164 else
165 {
166 Logger::put_l(
167 Logger::STANDARD_LOG, System::CIMSERVER,
168 Logger::INFORMATION,
169 "Server.ConsoleManager_zOS."
170 "CON_MODIFY_PLANNED.PEGASUS_OS_ZOS",
171 "Updated planned value for $0 to $1",
172 configProperty, propertyValue);
173 Logger::put_l(
174 Logger::STANDARD_LOG, System::CIMSERVER,
175 Logger::INFORMATION,
176 r.kieninger 1.1 "Server.ConsoleManager_zOS."
177 "CON_MODIFY_PLANNED2.PEGASUS_OS_ZOS",
178 "This change will become effective "
179 "after CIM Server restart.");
180 }
181 }
182
183 // It is unset, get current value which is default
184 if (currentValueIsNull)
185 {
186 currentValue = _configManager->getCurrentValue(configProperty);
187 }
|
188 r.kieninger 1.2 else
189 {
190 currentValue = propertyValue;
191 }
|
192 r.kieninger 1.1
193 // send notify config change message to ProviderManager Service
194 _sendNotifyConfigChangeMessage(String(configProperty),
195 currentValue,
|
196 thilo.boehm 1.4 !planned);
|
197 r.kieninger 1.1
198 PEG_AUDIT_LOG(logSetConfigProperty("OPERATOR",
199 configProperty,
200 preValue,
201 currentValue,
|
202 thilo.boehm 1.4 planned));
|
203 r.kieninger 1.1
204 }
205 catch (const NonDynamicConfigProperty& ndcp)
206 {
207 Logger::put_l(
208 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
209 "Server.ConsoleManager_zOS.CON_MODIFY_ERR.PEGASUS_OS_ZOS",
|
210 marek 1.5 "MODIFY command failed: \"$0\"",
|
211 r.kieninger 1.1 ndcp.getMessage());
212 }
213 catch (const InvalidPropertyValue& ipv)
214 {
215 Logger::put_l(
216 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
217 "Server.ConsoleManager_zOS.CON_MODIFY_ERR.PEGASUS_OS_ZOS",
|
218 marek 1.5 "MODIFY command failed: \"$0\"",
|
219 r.kieninger 1.1 ipv.getMessage());
220 }
221 catch (const UnrecognizedConfigProperty&)
222 {
223 Logger::put_l(
224 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
225 "Server.ConsoleManager_zOS.CON_MODIFY_INVALID.PEGASUS_OS_ZOS",
226 "$0 is not a valid configuration property",
227 configProperty);
228 }
229
230 PEG_METHOD_EXIT();
231 return;
232 }
233
234
235 void ZOSConsoleManager::processModifyCommand( char* command )
236 {
|
237 thilo.boehm 1.4 PEG_METHOD_ENTER(TRC_SERVER,
238 "ZOSConsoleManager::processModifyCommand");
|
239 r.kieninger 1.1
240 char* currentPtr = command;
241 char* cmdPtr = NULL;
242 char* cfgProperty = NULL;
243 char* cfgValue = NULL;
244 char* planned = NULL;
245 Boolean currentValueIsNull = false;
246
247
248 currentPtr = skipBlanks(currentPtr);
249
250 if (!memcmp(currentPtr,STRLIT_ARGS(ZOSCONSOLEMANAGER_TOKEN_APPL)))
251 {
252 currentPtr += strlen(ZOSCONSOLEMANAGER_TOKEN_APPL);
253 }
254 else
255 {
256 issueSyntaxError(command);
257 return;
258 }
259
260 r.kieninger 1.1 currentPtr = skipBlanks(currentPtr);
261
262 cfgProperty = currentPtr;
263 currentPtr = strchr(currentPtr,'=');
264
265 if (currentPtr==NULL)
266 {
267 issueSyntaxError(command);
268 return;
269 }
270 else
271 {
272 // skip the "="
273 *currentPtr = '\0';
274 currentPtr++;
275
276 currentPtr = skipBlanks(currentPtr);
277
278 if (*currentPtr == '\0')
279 {
280 currentValueIsNull=true;
281 r.kieninger 1.1 }
282 else if (*currentPtr == '\'')
283 {
284 char* temp = strchr(currentPtr+1,'\'');
285 if (temp!=NULL)
286 {
287 // skip the starting "'"
288 *currentPtr = '\0';
289 currentPtr++;
290
291 cfgValue = currentPtr;
292 currentPtr = temp;
293
294 // skip the ending "'"
295 *currentPtr = '\0';
296 currentPtr++;
297 }
298 else
299 {
300 issueSyntaxError(command);
301 return;
302 r.kieninger 1.1 }
303 }
304 else
305 {
306 cfgValue = currentPtr;
307 }
308 }
309
310 currentPtr = skipBlanks(currentPtr);
311
312 planned = strchr(currentPtr,',');
313 if (planned!=NULL)
314 {
315 *planned = '\0';
316 planned++;
317
318 planned = skipBlanks(planned);
319
320 if (memcmp(planned,STRLIT_ARGS(ZOSCONSOLEMANAGER_TOKEN_PLANNED)))
321 {
322 issueSyntaxError(command);
323 r.kieninger 1.1 return;
324 }
325 }
326
327
328 if (cfgProperty != NULL)
329 {
330 stripTrailingBlanks( cfgProperty );
331
332 PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
333 "Update property: %s", cfgProperty));
334 }
335
336 if (currentValueIsNull)
337 {
338 PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL4,
339 "Set property with null value");
340 }
341 else if (cfgValue != NULL)
342 {
343 stripTrailingBlanks( cfgValue );
344 r.kieninger 1.1
345 PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
346 "Update property value to: %s", cfgValue));
347 }
348
349 if (planned != NULL)
350 {
351 PEG_TRACE_CSTRING(TRC_SERVER, Tracer::LEVEL4,
352 "Updating planned value");
353 }
354
355 String propertyString(cfgProperty);
356 String propertyValue;
357
358 if (!currentValueIsNull)
359 {
360 propertyValue.assign(cfgValue);
361 }
362
363 updateConfiguration(propertyString,
364 propertyValue,
365 r.kieninger 1.1 currentValueIsNull,
366 planned);
367 PEG_METHOD_EXIT();
368 return;
369 }
370
371
372 void ZOSConsoleManager::startConsoleWatchThread(void)
373 {
|
374 thilo.boehm 1.4 PEG_METHOD_ENTER(TRC_SERVER,
375 "ZOSConsoleManager::startConsoleWatchThread");
|
376 r.kieninger 1.1
377 pthread_t thid;
378
379 if ( pthread_create(&thid,
380 NULL,
381 ZOSConsoleManager::consoleCommandWatchThread,
382 NULL) != 0 )
383 {
384 char str_errno2[10];
385 sprintf(str_errno2,"%08X",__errno2());
386 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
387 "Server.ConsoleManager_zOS.NO_CONSOLE_THREAD.PEGASUS_OS_ZOS",
388 "CIM Server Console command thread cannot be created: "
389 "$0 ( errno $1, reason code 0x$2 ).",
390 strerror(errno),
391 errno,
392 str_errno2);
393 }
394
395 PEG_METHOD_EXIT();
396 return;
397 r.kieninger 1.1 }
398
399
400
401 //
402 // z/OS console interface waiting for operator stop command
403 //
404 void* ZOSConsoleManager::consoleCommandWatchThread(void*)
405 {
|
406 thilo.boehm 1.4 PEG_METHOD_ENTER(TRC_SERVER,
407 "ZOSConsoleManager::consoleCommandWatchThread");
|
408 r.kieninger 1.1
409 struct __cons_msg cons;
410 int concmd=0;
411 char modstr[128];
412 int rc;
413
414 memset(&cons,0,sizeof(cons));
415 memset(modstr,0,sizeof(modstr));
416
417 do
418 {
419 rc = __console(&cons, modstr, &concmd);
420
421 if (rc != 0)
422 {
423 int errornumber = errno;
424 char str_errno2[10];
425 sprintf(str_errno2,"%08X",__errno2());
426
427 Logger::put_l(
428 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
429 r.kieninger 1.1 "Server.ConsoleManager_zOS.CONSOLE_ERROR.PEGASUS_OS_ZOS",
430 "Console Communication Service failed:"
431 "$0 ( errno $1, reason code 0x$2 ).",
432 strerror(errornumber),
433 errornumber,
434 str_errno2);
435
436 break;
437 }
438
439 // Check if we received a stop command from the console
440 if (concmd == _CC_modify)
441 {
442 // Ensure the command we received from the console is
443 // null terminated.
444 modstr[127] = '\0';
445
446 PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
447 "Received MODIFY command: %s", modstr));
448
449 processModifyCommand(modstr);
450 r.kieninger 1.1 }
451 else if (concmd != _CC_stop)
452 {
453 // Just issue a console message that the command was
454 // not recognized and wait again for the stop command.
455 Logger::put_l(
456 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
457 "Server.ConsoleManager_zOS.CONSOLE_NO_MODIFY.PEGASUS_OS_ZOS",
458 "Command not recognized by CIM server.");
459 }
460 else
461 {
462 Logger::put_l(
463 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
464 "Server.ConsoleManager_zOS.CONSOLE_STOP.PEGASUS_OS_ZOS",
465 "STOP command received from z/OS console,"
466 " initiating shutdown.");
467 }
468
469 // keep on until we encounter an error or received a STOP
470 } while ( (concmd != _CC_stop) && (rc == 0) );
471 r.kieninger 1.1
472 CIMServer::shutdownSignal();
473
474 PEG_METHOD_EXIT();
475 pthread_exit(0);
476
477 return NULL;
478 }
479
480
481 //
482 // Send notify config change message to provider manager service
483 // This code was borrowed from the ConfigSettingProvider and should
484 // be kept in sync.
485 // The purpose is to ensure that OOP agents also get the update.
486 // TBD, or is it for other reasons as well?
487 //
488 void ZOSConsoleManager::_sendNotifyConfigChangeMessage(
489 const String& propertyName,
490 const String& newPropertyValue,
491 Boolean currentValueModified)
492 r.kieninger 1.1 {
|
493 thilo.boehm 1.4 PEG_METHOD_ENTER(TRC_SERVER,
|
494 r.kieninger 1.1 "ZOSConsoleManager::_sendNotifyConfigChangeMessage");
495
496 ModuleController* controller = ModuleController::getModuleController();
497
498 MessageQueue * queue = MessageQueue::lookup(
499 PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
500
501 MessageQueueService * service = dynamic_cast<MessageQueueService *>(queue);
502
503 if (service != NULL)
504 {
505 // create CIMNotifyConfigChangeRequestMessage
506 CIMNotifyConfigChangeRequestMessage * notify_req =
507 new CIMNotifyConfigChangeRequestMessage (
508 XmlWriter::getNextMessageId (),
509 propertyName,
510 newPropertyValue,
511 currentValueModified,
512 QueueIdStack(service->getQueueId()));
513
514 // create request envelope
515 r.kieninger 1.1 AsyncLegacyOperationStart asyncRequest(
516 NULL,
517 service->getQueueId(),
518 notify_req,
519 service->getQueueId());
520
521 AutoPtr<AsyncReply> asyncReply(
522 controller->ClientSendWait(service->getQueueId(), &asyncRequest));
523
524 AutoPtr<CIMNotifyConfigChangeResponseMessage> response(
525 reinterpret_cast<CIMNotifyConfigChangeResponseMessage *>(
526 (static_cast<AsyncLegacyOperationResult *>
527 (asyncReply.get()))->get_result()));
528
529 if (response->cimException.getCode() != CIM_ERR_SUCCESS)
530 {
531 CIMException e = response->cimException;
532 PEG_METHOD_EXIT();
533 throw (e);
534 }
535 }
536 r.kieninger 1.1 PEG_METHOD_EXIT();
537 }
538
539
540
541 PEGASUS_NAMESPACE_END
|