1 karl 1.179 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.32 //
|
3 karl 1.141 // 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 karl 1.121 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.141 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.149 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.179 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.32 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.58 // 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 mike 1.32 // 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 karl 1.179 //
|
21 kumpf 1.58 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.32 // 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 kumpf 1.58 // 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 mike 1.32 // 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 mike 1.211.2.10 //==============================================================================
31 //
|
32 mike 1.32 //%/////////////////////////////////////////////////////////////////////////////
33
|
34 mike 1.211.2.10
35 //////////////////////////////////////////////////////////////////////
36 //
37 // Notes on daemon operation (Unix) and service operation (Win 32):
38 //
39 // To run pegasus as a daemon on Unix platforms:
40 //
41 // cimserver
42 //
43 // To NOT run pegasus as a daemon on Unix platforms, set the daemon config
44 // property to false:
45 //
46 // cimserver daemon=false
47 //
48 // The daemon config property has no effect on windows operation.
49 //
50 // To shutdown pegasus, use the -s option:
51 //
52 // cimserver -s
53 //
54 // To run pegasus as an NT service, there are FOUR different possibilities:
55 mike 1.211.2.10 //
56 // To INSTALL the Pegasus service,
57 //
58 // cimserver -install
59 //
60 // To REMOVE the Pegasus service,
61 //
62 // cimserver -remove
63 //
64 // To START the Pegasus service,
65 //
66 // net start cimserver
67 // or
68 // cimserver -start
69 //
70 // To STOP the Pegasus service,
71 //
72 // net stop cimserver
73 // or
74 // cimserver -stop
75 //
76 mike 1.211.2.10 // Alternatively, you can use the windows service manager. Pegasus shows up
77 // in the service database as "Pegasus CIM Object Manager"
78 //
79 //////////////////////////////////////////////////////////////////////
80
81
82 #include <Pegasus/Common/Config.h>
83 #include <Pegasus/Common/Constants.h>
84 #include <Pegasus/Common/PegasusAssert.h>
85 #include <Pegasus/Common/FileSystem.h>
86 #include <Pegasus/Common/PegasusVersion.h>
87 #include <Pegasus/Common/Logger.h>
88 #include <Pegasus/Common/System.h>
89 #include <Pegasus/Common/Tracer.h>
90 #include <Pegasus/Common/LanguageParser.h>
91 #include <Pegasus/Config/ConfigManager.h>
92 #include <Pegasus/Server/CIMServer.h>
93 #include <Service/ServerProcess.h>
94 #include <Service/ServerRunStatus.h>
95
|
96 mike 1.211.2.13 #if !defined(PEGASUS_REMOVE_SERVER_CLIENT_USAGE)
97 # include <Pegasus/Client/CIMClient.h>
98 # include <Service/ServerShutdownClient.h>
99 #endif
100
|
101 mike 1.211.2.10 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
102 #include <Pegasus/Common/SetFileDescriptorToEBCDICEncoding.h>
103 #include <Service/ARM_zOS.h>
104 # ifdef PEGASUS_ZOS_SECURITY
105 // This include file will not be provided in the OpenGroup CVS for now.
106 // Do NOT try to include it in your compile
107 # include <Pegasus/Common/safCheckzOS_inline.h>
108 # endif
109 #endif
110
111 #if defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VXWORKS)
112 # include <unistd.h>
113 # include <sys/types.h>
114 # include <sys/stat.h>
115 # include <fcntl.h>
116 #endif
117
118 #ifdef PEGASUS_ENABLE_PRIVILEGE_SEPARATION
119 # define PEGASUS_PROCESS_NAME "cimservermain"
120 #else
121 # define PEGASUS_PROCESS_NAME "cimserver"
122 mike 1.211.2.10 #endif
123
124 #include <Pegasus/Common/Executor.h>
125
126 #ifdef PEGASUS_OS_PASE
127 # include <ILEWrapper/ILEUtilities2.h>
128 # include <ILEWrapper/qumemultiutil.h>
129 #endif
|
130 ouyang.jian 1.206
|
131 kumpf 1.119 PEGASUS_USING_PEGASUS;
|
132 mike 1.211.2.10 PEGASUS_USING_STD;
133
134 //Windows service variables are not defined elsewhere in the product
135 //enable ability to override these
136 #ifndef PEGASUS_SERVICE_NAME
137 #define PEGASUS_SERVICE_NAME "Pegasus CIM Object Manager";
138 #endif
139 #ifndef PEGASUS_SERVICE_DESCRIPTION
140 #define PEGASUS_SERVICE_DESCRIPTION "Pegasus CIM Object Manager Service";
141 #endif
142
143 #ifdef PEGASUS_OS_PASE
144 #include <as400_protos.h> //for _SETCCSID
145 #endif
146
147 class PEGASUS_SERVER_LINKAGE CIMServerProcess : public ServerProcess
148 {
149 public:
150
151 CIMServerProcess()
152 {
153 mike 1.211.2.10 cimserver_set_process(this);
154 }
155
156 virtual ~CIMServerProcess()
157 {
158 }
159
160 //defined in PegasusVersion.h
161 virtual const char* getProductName() const
162 {
163 return PEGASUS_PRODUCT_NAME;
164 }
165
166 virtual const char* getExtendedName() const
167 {
168 return PEGASUS_SERVICE_NAME;
169 }
170
171 virtual const char* getDescription() const
172 {
173 return PEGASUS_SERVICE_DESCRIPTION;
174 mike 1.211.2.10 }
175
176 //defined in PegasusVersion.h
177 virtual const char* getCompleteVersion() const
178 {
179 if (*PEGASUS_PRODUCT_STATUS == '\0' )
180 return PEGASUS_PRODUCT_VERSION;
181 else
182 return PEGASUS_PRODUCT_VERSION " " PEGASUS_PRODUCT_STATUS;
183 }
184
185 //defined in PegasusVersion.h
186 virtual const char* getVersion() const
187 {
188 return PEGASUS_PRODUCT_VERSION;
189 }
190
191 virtual const char* getProcessName() const
192 {
193 return PEGASUS_PROCESS_NAME;
194 }
195 mike 1.211.2.10
196 int cimserver_run(
197 int argc,
198 char** argv,
199 Boolean shutdownOption,
200 Boolean debugOutputOption);
201
202 void cimserver_stop();
203 };
204
205 ServerRunStatus _serverRunStatus(
206 PEGASUS_PROCESS_NAME, PEGASUS_CIMSERVER_START_FILE);
207 AutoPtr<CIMServerProcess> _cimServerProcess(new CIMServerProcess());
208 static CIMServer* _cimServer = 0;
209 static Thread* dummyInitialThread = 0;
210
211 //
212 // The command name.
213 //
214 static const char COMMAND_NAME [] = "cimserver";
215
216 mike 1.211.2.10 //
217 // The constant defining usage string.
218 //
219 static const char USAGE [] = "Usage: ";
220
221 /**
222 Constants representing the command line options.
223 */
224 static const char OPTION_VERSION = 'v';
225
226 static const char OPTION_HELP = 'h';
227
228 static const char OPTION_HOME = 'D';
229
230 static const char OPTION_SHUTDOWN = 's';
231
232 static const char LONG_HELP[] = "help";
233
234 static const char LONG_VERSION[] = "version";
235
236 static const char OPTION_DEBUGOUTPUT = 'X';
237 mike 1.211.2.10
238 /** GetOptions function - This function defines the Options Table
239 and sets up the options from that table using the config manager.
240
241 Some possible exceptions: NoSuchFile, FileNotReadable, CannotRenameFile,
242 ConfigFileSyntaxError, UnrecognizedConfigProperty, InvalidPropertyValue,
243 CannotOpenFile.
244 */
245 void GetOptions(
246 ConfigManager* cm,
247 int& argc,
248 char** argv,
249 Boolean shutdownOption)
250 {
251 #if defined(PEGASUS_OS_VXWORKS)
252
253 // VxWorks does not use configuration files.
254
255 cm->mergeCommandLine(argc, argv);
256
257 #else /* PEGASUS_OS_VXWORKS */
258 mike 1.211.2.10
259 if (shutdownOption)
260 {
261 cm->loadConfigFiles();
262 }
263 else
264 {
265 cm->mergeConfigFiles();
266 }
267
268 // Temporarily disable updates to the current configuration
269 // file if shutdownOption is true
270 cm->useConfigFiles = (shutdownOption==false);
271
272 cm->mergeCommandLine(argc, argv);
273
274 // Enable updates again
275 cm->useConfigFiles = true;
276
277 #endif /* PEGASUS_OS_VXWORKS */
278 }
279 mike 1.211.2.10
280 /* PrintHelp - This is temporary until we expand the options manager to allow
281 options help to be defined with the OptionRow entries and presented from
282 those entries.
283 */
284 void PrintHelp(const char* arg0)
285 {
286 String usage = String (USAGE);
287 usage.append(COMMAND_NAME);
288 usage.append(" [ [ options ] | [ configProperty=value, ... ] ]\n");
289 usage.append(" options\n");
290 usage.append(" -v, --version - displays CIM Server version number\n");
291 usage.append(" -h, --help - prints this help message\n");
292 usage.append(" -s - shuts down CIM Server\n");
293 #if !defined(PEGASUS_USE_RELEASE_DIRS)
294 usage.append(" -D [home] - sets pegasus home directory\n");
295 #endif
296 #if defined(PEGASUS_OS_TYPE_WINDOWS)
297 usage.append(" -install [name] - installs pegasus as a Windows "
298 "Service\n");
299 usage.append(" [name] is optional and overrides "
300 mike 1.211.2.10 "the\n");
301 usage.append(" default CIM Server Service Name\n");
302 usage.append(" by appending [name]\n");
303 usage.append(" -remove [name] - removes pegasus as a Windows "
304 "Service\n");
305 usage.append(" [name] is optional and overrides "
306 "the\n");
307 usage.append(" default CIM Server Service Name\n");
308 usage.append(" by appending [name]\n");
309 usage.append(" -start [name] - starts pegasus as a Windows Service\n");
310 usage.append(" [name] is optional and overrides "
311 "the\n");
312 usage.append(" default CIM Server Service Name\n");
313 usage.append(" by appending [name]\n");
314 usage.append(" -stop [name] - stops pegasus as a Windows Service\n");
315 usage.append(" [name] is optional and overrides "
316 "the\n");
317 usage.append(" default CIM Server Service Name\n");
318 usage.append(" by appending [name]\n\n");
319 #endif
320 usage.append(" configProperty=value\n");
321 mike 1.211.2.10 usage.append(" - sets CIM Server configuration "
322 "property\n");
323
324 cout << endl;
325 cout << _cimServerProcess->getProductName() << " " <<
326 _cimServerProcess->getCompleteVersion() << endl;
327 cout << endl;
328
329 #if defined(PEGASUS_OS_TYPE_WINDOWS)
330 MessageLoaderParms parms("src.Server.cimserver.MENU.WINDOWS", usage);
331 #elif defined(PEGASUS_USE_RELEASE_DIRS)
332 MessageLoaderParms parms(
333 "src.Server.cimserver.MENU.HPUXLINUXIA64GNU",
334 usage);
335 #else
336 MessageLoaderParms parms("src.Server.cimserver.MENU.STANDARD", usage);
337 #endif
338 cout << MessageLoader::getMessage(parms) << endl;
339 }
340
341 // This needs to be called at various points in the code depending on the
342 mike 1.211.2.10 // platform and error conditions.
343 // We need to delete the _cimServer reference on exit in order for the
344 // destructors to get called.
345 void deleteCIMServer()
346 {
347 delete _cimServer;
348 _cimServer = 0;
349
350 if (dummyInitialThread)
351 {
352 Thread::clearLanguages();
353 delete dummyInitialThread;
354 }
355 }
356
357 //
358 // Dummy function for the Thread object associated with the initial thread.
359 // Since the initial thread is used to process CIM requests, this is
360 // needed to localize the exceptions thrown during CIM request processing.
361 // Note: This function should never be called!
362 //
363 mike 1.211.2.10 ThreadReturnType PEGASUS_THREAD_CDECL dummyThreadFunc(void* parm)
364 {
365 return (ThreadReturnType)0;
366 }
367
368 #ifdef PEGASUS_ENABLE_PRIVILEGE_SEPARATION
369
370 static int _extractExecutorSockOpt(int& argc, char**& argv)
371 {
372 // Extract the "--executor-socket <sock>" option if any. This indicates
373 // that the e[x]ecutor is running. The option argument is the socket used
374 // to communicate with the executor. Remove the option from the
375 // argv list and decrease argc by two.
376
377 int sock = -1;
378 const char OPT[] = "--executor-socket";
379
380 for (int i = 1; i < argc; i++)
381 {
382 if (strcmp(argv[i], OPT) == 0)
383 {
384 mike 1.211.2.10 // Check for missing option argument.
385
386 if (i + 1 == argc)
387 {
388 MessageLoaderParms parms(
389 "src.Server.cimserver.MISSING_OPTION_ARGUMENT",
390 "Missing argument for $0 option.",
391 OPT);
392 cerr << argv[0] << ": " << MessageLoader::getMessage(parms) <<
393 endl;
394 exit(1);
395 }
396
397 // Convert argument to positive integer.
398
399 char* end;
400 unsigned long x = strtoul(argv[i+1], &end, 10);
401
402 // Check whether option argument will fit in a signed integer.
403
404 if (*end != '\0' || x > 2147483647)
405 mike 1.211.2.10 {
406 MessageLoaderParms parms(
407 "src.Server.cimserver.BAD_OPTION_ARGUMENT",
408 "Bad $0 option argument: $1.",
409 OPT,
410 argv[i+1]);
411 cerr << argv[0] << ": " << MessageLoader::getMessage(parms) <<
412 endl;
413 exit(1);
414 }
415
416 sock = int(x);
417
418 // Remove "-x <sock>" from argv-argc.
419
420 memmove(argv + i, argv + i + 2, sizeof(char*) * (argc - i - 1));
421 argc -= 2;
422 break;
423 }
424 }
425
426 mike 1.211.2.10 if (sock == -1)
427 {
428 MessageLoaderParms parms(
429 "src.Server.cimserver.MISSING_OPTION",
430 "Missing $0 option.",
431 OPT);
432 cerr << argv[0] << ": " << MessageLoader::getMessage(parms) << endl;
433 exit(1);
434 }
435
436 return sock;
437 }
438
439 #endif /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION */
440
441 /////////////////////////////////////////////////////////////////////////
442 // MAIN
443 //////////////////////////////////////////////////////////////////////////
444
445 extern "C" int PegasusServerMain(int argc, char** argv)
446 {
447 mike 1.211.2.10 String pegasusHome;
448 Boolean shutdownOption = false;
449 Boolean debugOutputOption = false;
450
451 // Set Message loading to process locale
452 MessageLoader::_useProcessLocale = true;
453
454 #ifdef PEGASUS_OS_ZOS
455 // Direct standard input to /dev/null,
456 close(STDIN_FILENO);
457 open("/dev/null", O_RDONLY);
458
459 if ( setEBCDICEncoding(STDOUT_FILENO)==-1 ||
460 setEBCDICEncoding(STDERR_FILENO)==-1 )
461 {
462 PEG_TRACE_CSTRING(TRC_SERVER,Tracer::LEVEL4,
463 "Coud not set stdout or stderr to EBCDIC encoding.");
464 }
465 // Need to initialize timezone information in the
466 // initial processing thread (IPT)
467 tzset();
468 mike 1.211.2.10 #endif
469
470 #if defined(PEGASUS_OS_AIX) && defined(PEGASUS_HAS_MESSAGES)
471 setlocale(LC_ALL, "");
472 #endif
473
474 #ifndef PEGASUS_OS_TYPE_WINDOWS
475 //
476 // Get environment variables:
477 //
478 # if defined(PEGASUS_OS_AIX) && defined(PEGASUS_USE_RELEASE_DIRS)
479 pegasusHome = AIX_RELEASE_PEGASUS_HOME;
480 # elif defined(PEGASUS_OS_PASE)
481 const char *tmp = getenv("PEGASUS_HOME");
482 pegasusHome = (tmp == 0) ? PASE_DEFAULT_PEGASUS_HOME : tmp;
483 # elif !defined(PEGASUS_USE_RELEASE_DIRS) || \
484 defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
485 const char* tmp = getenv("PEGASUS_HOME");
486
487 if (tmp)
488 {
489 mike 1.211.2.10 pegasusHome = tmp;
490 }
491 # endif
492
493 FileSystem::translateSlashes(pegasusHome);
494 #else
495
496 // windows only
497 //setHome(pegasusHome);
498 pegasusHome = _cimServerProcess->getHome();
499 #endif
500
501 #ifdef PEGASUS_ENABLE_PRIVILEGE_SEPARATION
502
503 // If invoked with "--executor-socket <socket>" option, then use executor.
504
505 Executor::setSock(_extractExecutorSockOpt(argc, argv));
506
507 // Ping executor to verify the specified socket is valid.
508
509 if (Executor::ping() != 0)
510 mike 1.211.2.10 {
511 MessageLoaderParms parms("src.Server.cimserver.EXECUTOR_PING_FAILED",
512 "Failed to ping the executor on the specified socket.");
513 cerr << argv[0] << ": " << MessageLoader::getMessage(parms) << endl;
514 exit(1);
515 }
516
517 #endif /* !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
518
519 // Get help, version, and shutdown options
520
521 for (int i = 1; i < argc; )
522 {
523 const char* arg = argv[i];
524 if (String::equal(arg,"--help"))
525 {
526 PrintHelp(argv[0]);
527 exit(0);
528 }
529 else if (String::equal(arg,"--version"))
530 {
531 mike 1.211.2.10 cout << _cimServerProcess->getCompleteVersion() << endl;
532 exit(0);
533 }
534 // Check for -option
535 else if (*arg == '-')
536 {
537 // Get the option
538 const char* option = arg + 1;
539
540 //
541 // Check to see if user asked for the version (-v option):
542 //
543 if (*option == OPTION_VERSION &&
544 strlen(option) == 1)
545 {
546 cout << _cimServerProcess->getCompleteVersion() << endl;
547 exit(0);
548 }
549 //
550 // Check to see if user asked for help (-h option):
551 //
552 mike 1.211.2.10 else if (*option == OPTION_HELP &&
553 (strlen(option) == 1))
554 {
555 PrintHelp(argv[0]);
556 exit(0);
557 }
558 #if !defined(PEGASUS_USE_RELEASE_DIRS)
559 else if (*option == OPTION_HOME &&
560 (strlen(option) == 1))
561 {
562 if (i + 1 < argc)
563 {
564 pegasusHome.assign(argv[i + 1]);
565 }
566 else
567 {
568 String opt(option);
569 MessageLoaderParms parms(
570 "src.Server.cimserver.MISSING_ARGUMENT",
571 "Missing argument for option -$0",
572 opt);
573 mike 1.211.2.10 cout << MessageLoader::getMessage(parms) << endl;
574 exit(0);
575 }
576
577 memmove(&argv[i], &argv[i + 2], (argc-i-1) * sizeof(char*));
578 argc -= 2;
579 }
580 #endif
581 //
582 // Check to see if user asked for debug output (-X option):
583 //
584 else if (*option == OPTION_DEBUGOUTPUT &&
585 (strlen(option) == 1))
586 {
587 MessageLoaderParms parms(
588 "src.Server.cimserver.UNSUPPORTED_DEBUG_OPTION",
589 "Unsupported debug output option is enabled.");
590 cout << MessageLoader::getMessage(parms) << endl;
591
592 debugOutputOption = true;
593
594 mike 1.211.2.10 #if defined(PEGASUS_OS_HPUX)
595 System::bindVerbose = true;
596 #endif
597
598 // remove the option from the command line
599 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
600 argc--;
601 }
602 //
603 // Check to see if user asked for shutdown (-s option):
604 //
605 else if (*option == OPTION_SHUTDOWN &&
606 (strlen(option) == 1))
607 {
608 //
609 // Check to see if shutdown has already been specified:
610 //
611 if (shutdownOption)
612 {
613 MessageLoaderParms parms(
614 "src.Server.cimserver.DUPLICATE_SHUTDOWN_OPTION",
615 mike 1.211.2.10 "Duplicate shutdown option specified.");
616
617 cout << MessageLoader::getMessage(parms) << endl;
618 exit(0);
619 }
620
621 shutdownOption = true;
622
623 // remove the option from the command line
624 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
625 argc--;
626 }
627 else
628 i++;
629 }
630 else
631 i++;
632 }
633
634 //
635 // Set the value for pegasusHome property
636 mike 1.211.2.10 //
637 ConfigManager::setPegasusHome(pegasusHome);
638
639 //
640 // Do the platform specific run
641 //
642
643 return _cimServerProcess->platform_run(
644 argc, argv, shutdownOption, debugOutputOption);
645 }
646
647 void CIMServerProcess::cimserver_stop()
648 {
649 _cimServer->shutdownSignal();
650 }
651
652 //
653 // The main, common, running code
654 //
655 // NOTE: Do NOT call exit(). Use return(), otherwise some platforms
656 // will fail to shutdown properly/cleanly.
657 mike 1.211.2.10 //
658 // TODO: Current change minimal for platform "service" shutdown bug fixes.
659 // Perhaps further extract out common stuff and put into main(), put
660 // daemon stuff into platform specific platform_run(), etc.
661 // Note: make sure to not put error handling stuff that platform
662 // specific runs may need to deal with better (instead of exit(), etc).
663 //
664
665 int CIMServerProcess::cimserver_run(
666 int argc,
667 char** argv,
668 Boolean shutdownOption,
669 Boolean debugOutputOption)
670 {
671 Boolean daemonOption = false;
672
673 #if defined (PEGASUS_OS_PASE) && !defined (PEGASUS_DEBUG)
674 // PASE have itself regular for checking privileged user
675 if (!System::isPrivilegedUser("*CURRENT "))
676 {
677 MessageLoaderParms parms(
678 mike 1.211.2.10 "src.Server.cimserver.NO_AUTHORITY.PEGASUS_OS_PASE",
679 "The caller should be a privileged user,"
680 " or the server will not run.");
681 cerr << MessageLoader::getMessage(parms) << endl;
682 exit (1);
683 }
684 char jobName[11];
685 // this function only can be found in PASE environment
686 umeGetJobName(jobName, false);
687 if (strncmp("QUMECIMOM ", jobName, 10) != 0
688 && strncmp("QUMEENDCIM", jobName, 10) != 0)
689 {
690 MessageLoaderParms parms(
691 "src.Server.cimserver.NOT_OFFICIAL_START.PEGASUS_OS_PASE",
692 "cimserver can not be started by user.\nServer will not run.");
693 cerr << MessageLoader::getMessage(parms) << endl;
694 exit (1);
695 }
696
697 // Direct standard input, output, and error to /dev/null,
698 // PASE run this job in background, any output in not allowed
699 mike 1.211.2.10 freopen("/dev/null", "r", stdin);
700 freopen("/dev/null", "w", stdout);
701 freopen("/dev/null", "w", stderr);
702 #endif
703
704 //
705 // Get an instance of the Config Manager.
706 //
707 ConfigManager* configManager = ConfigManager::getInstance();
708
709 #if !defined(PEGASUS_OS_VXWORKS)
710 configManager->useConfigFiles = true;
711 #endif
712
713 try
714 {
715 //
716 // Get options (from command line and from configuration file); this
717 // removes corresponding options and their arguments from the command
718 // line. NOTE: If shutdownOption=true, the contents of current config
719 // file are not overwritten by the planned config file.
720 mike 1.211.2.10 //
721 GetOptions(configManager, argc, argv, shutdownOption);
722
723 //
724 // Initialize the message home directory in the MessageLoader.
725 // This is the default directory where the resource bundles are found.
726 //
727 MessageLoader::setPegasusMsgHome(ConfigManager::getHomedPath(
728 ConfigManager::getInstance()->getCurrentValue("messageDir")));
729
730 #ifdef PEGASUS_OS_PASE
731 // set ccsid to unicode for entire job
732 // ccsid is globolization mechanism in PASE environment
733 if (_SETCCSID(1208) == -1)
734 {
735 MessageLoaderParms parms(
736 "src.Server.cimserver.SET_CCSID_ERROR.PEGASUS_OS_PASE",
737 "Failed to set CCSID, server will stop.");
738 cerr << MessageLoader::getMessage(parms) << endl;
739 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::FATAL,
740 "src.Server.cimserver.SET_CCSID_ERROR.PEGASUS_OS_PASE",
741 mike 1.211.2.10 "Failed to set CCSID, server will stop.\n");
742 exit (1);
743 }
744
745 char fullJobName[29];
746 umeGetJobName(fullJobName, true);
747 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
748 "src.Server.cimserver.SERVER_JOB_NAME.PEGASUS_OS_PASE",
749 "CIM Server's Job Name is: $0", fullJobName);
750 #endif
751
752 Boolean enableHttpConnection = ConfigManager::parseBooleanValue(
753 configManager->getCurrentValue("enableHttpConnection"));
754 Boolean enableHttpsConnection = ConfigManager::parseBooleanValue(
755 configManager->getCurrentValue("enableHttpsConnection"));
756
757 // Make sure at least one connection is enabled
758 #ifdef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
759 if (!enableHttpConnection && !enableHttpsConnection)
760 {
761 //l10n
762 mike 1.211.2.10 //Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
763 //"Neither HTTP nor HTTPS connection is enabled. "
764 //"CIMServer will not be started.");
765 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
766 "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
767 "Neither HTTP nor HTTPS connection is enabled."
768 " CIMServer will not be started.");
769 //cerr << "Neither HTTP nor HTTPS connection is enabled. "
770 //"CIMServer will not be started." << endl;
771 MessageLoaderParms parms(
772 "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
773 "Neither HTTP nor HTTPS connection is enabled."
774 " CIMServer will not be started.");
775 cerr << MessageLoader::getMessage(parms) << endl;
776 return(1);
777 }
778 #endif
779 //
780 // Check to see if we should start Pegasus as a daemon
781 //
782
783 mike 1.211.2.10 daemonOption = ConfigManager::parseBooleanValue(
784 configManager->getCurrentValue("daemon"));
785
786 #if !defined(PEGASUS_USE_SYSLOGS)
787 String logsDirectory = ConfigManager::getHomedPath(
788 configManager->getCurrentValue("logdir"));
789
790 // Set up the Logger. This does not open the logs.
791 // Might be more logical to clean before set.
792 Logger::setHomeDirectory(logsDirectory);
793
794 # ifdef PEGASUS_OS_PASE
795 /* write job log to tell where pegasus log is.*/
796 if(logsDirectory.size() > 0)
797 // this function only can be found in PASE environment
798 logPegasusDir2joblog(logsDirectory.getCString());
799 else
800 logPegasusDir2joblog(".");
801 # endif
802 #endif
803
|
804 mike 1.211.2.13 //
805 // Some platforms do not support using client to shutdown server.
806 //
807 #if !defined(PEGASUS_REMOVE_SERVER_CLIENT_USAGE)
|
808 mike 1.211.2.10 //
809 // Check to see if we need to shutdown CIMOM
810 //
811 if (shutdownOption)
812 {
813 String configTimeout =
814 configManager->getCurrentValue("shutdownTimeout");
815 Uint32 timeoutValue =
816 strtol(configTimeout.getCString(), (char **)0, 10);
|
817 mike 1.211.2.13 # ifdef PEGASUS_SLP_REG_TIMEOUT
|
818 mike 1.211.2.10 // To deregister Pegasus with SLP
819 unregisterPegasusFromSLP();
|
820 mike 1.211.2.13 # endif
|
821 mike 1.211.2.10
822 ServerShutdownClient serverShutdownClient(&_serverRunStatus);
823 serverShutdownClient.shutdown(timeoutValue);
824
825 MessageLoaderParms parms(
826 "src.Server.cimserver.SERVER_STOPPED",
827 "CIM Server stopped.");
828
829 cout << MessageLoader::getMessage(parms) << endl;
830 return 0;
831 }
|
832 mike 1.211.2.13 #endif /* PEGASUS_REMOVE_SERVER_CLIENT_USAGE */
|
833 mike 1.211.2.10
834 #if defined(PEGASUS_DEBUG) && !defined(PEGASUS_USE_SYSLOGS)
835 // Leave this in until people get familiar with the logs.
836 MessageLoaderParms parms("src.Server.cimserver.LOGS_DIRECTORY",
837 "Logs Directory = ");
838 cout << MessageLoader::getMessage(parms) << logsDirectory << endl;
839 #endif
840 }
841 catch (Exception& e)
842 {
843 MessageLoaderParms parms("src.Server.cimserver.SERVER_NOT_STARTED",
844 "cimserver not started: $0", e.getMessage());
845 Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
846 MessageLoader::getMessage(parms));
847 cerr << MessageLoader::getMessage(parms) << endl;
848
849 return 1;
850 }
851
852 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) && defined(PEGASUS_ZOS_SECURITY)
853 startupCheckBPXServer(true);
854 mike 1.211.2.10 startupCheckProfileCIMSERVclassWBEM();
855 startupEnableMSC();
856 #endif
857
858 #if defined(PEGASUS_DEBUG)
859 // Put out startup up message.
860 cout << _cimServerProcess->getProductName() << " " <<
861 _cimServerProcess->getCompleteVersion() << endl;
862 #endif
863
864 // reset message loading to NON-process locale
865 MessageLoader::_useProcessLocale = false;
866
867 // Get the parent's PID before forking
868 _serverRunStatus.setParentPid(System::getPID());
869
870 // Do not fork when using privilege separation (executor will daemonize
871 // itself later).
872 if (daemonOption)
873 {
874 if (-1 == _cimServerProcess->cimserver_fork())
875 mike 1.211.2.10 return -1;
876 }
877
878 // Now we are after the fork...
879 // Create a dummy Thread object that can be used to store the
880 // AcceptLanguageList object for CIM requests that are serviced
881 // by this thread (initial thread of server). Need to do this
882 // because this thread is not in a ThreadPool, but is used
883 // to service CIM requests.
884 // The run function for the dummy Thread should never be called,
885 dummyInitialThread = new Thread(dummyThreadFunc, NULL, false);
886 Thread::setCurrent(dummyInitialThread);
887 AcceptLanguageList default_al;
888 try
889 {
890 default_al = LanguageParser::getDefaultAcceptLanguages();
891 Thread::setLanguages(new AcceptLanguageList(default_al));
892 }
893 catch (InvalidAcceptLanguageHeader& e)
894 {
895 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
896 mike 1.211.2.10 "src.Server.cimserver.FAILED_TO_SET_PROCESS_LOCALE",
897 "Could not convert the system process locale into a valid "
898 "AcceptLanguage format.");
899 Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
900 e.getMessage());
901 }
902
903 #if !defined(PEGASUS_OS_TYPE_WINDOWS) && !defined(PEGASUS_OS_VXWORKS)
904 umask(S_IRWXG|S_IRWXO);
905 #endif
906
907 // Start up the CIM Server
908
909 try
910 {
|
911 karl 1.211.2.11 #if defined(PEGASUS_OS_TYPE_UNIX)
912
913 // ATTN KS This file not used for VxWorks
|
914 mike 1.211.2.10 //
915 // Lock the CIMSERVER_LOCK_FILE during CIM Server start-up to prevent
916 // concurrent writes to this file by multiple cimserver processes
917 // starting at the same time.
918 //
919 CString startupLockFileName = ConfigManager::getHomedPath(
920 PEGASUS_CIMSERVER_START_LOCK_FILE).getCString();
921
922 // Make sure the start-up lock file exists
923 FILE* startupLockFile;
924 if ((startupLockFile = fopen(startupLockFileName, "w")) != 0)
925 {
926 fclose(startupLockFile);
927 }
928
929 AutoFileLock fileLock(startupLockFileName);
930 #endif
931
932 #if defined(PEGASUS_OS_TYPE_UNIX) || \
933 defined(PEGASUS_OS_VMS) || \
934 defined(PEGASUS_OS_VXWORKS)
935 mike 1.211.2.10 //
936 // Check if a CIM Server is already running. If so, print an error
937 // message and notify the parent process (if there is one) to terminate
938 //
939 if (_serverRunStatus.isServerRunning())
940 {
941 MessageLoaderParms parms(
942 "src.Server.cimserver.UNABLE_TO_START_SERVER_ALREADY_RUNNING",
943 "Unable to start CIMServer. CIMServer is already running.");
944 Logger::put(
945 Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
946 MessageLoader::getMessage(parms));
947 cerr << MessageLoader::getMessage(parms) << endl;
948
949 if (daemonOption)
950 {
951 _cimServerProcess->notify_parent(1);
952 }
953
954 return 1;
955 }
956 mike 1.211.2.10
957 //
958 // Declare ourselves as the running CIM Server process, and write our
959 // PID to the PID file.
960 //
961 _serverRunStatus.setServerRunning();
962 #endif
963
964 // Create and initialize the CIMServer object
965
966 _cimServer = new CIMServer();
967
968 Boolean enableHttpConnection = ConfigManager::parseBooleanValue(
969 configManager->getCurrentValue("enableHttpConnection"));
970 Boolean enableHttpsConnection = ConfigManager::parseBooleanValue(
971 configManager->getCurrentValue("enableHttpsConnection"));
972
973 #ifdef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
974 // Make sure at least one connection is enabled
975 if (!enableHttpConnection && !enableHttpsConnection)
976 {
977 mike 1.211.2.10 MessageLoaderParms parms(
978 "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
979 "Neither HTTP nor HTTPS connection is enabled.");
980 throw Exception(parms);
981 }
982 #endif
983
984 Boolean addIP6Acceptor = false;
985 Boolean addIP4Acceptor = false;
986
987 #ifdef PEGASUS_OS_TYPE_WINDOWS
988 addIP4Acceptor = true;
989 #endif
990
991 #ifdef PEGASUS_ENABLE_IPV6
992 // If IPv6 stack is disabled swicth to IPv4 stack.
993 if (System::isIPv6StackActive())
994 {
995 addIP6Acceptor = true;
996 }
997 else
998 mike 1.211.2.10 {
999 MessageLoaderParms parms(
1000 "src.Server.cimserver.IPV6_STACK_NOT_ACTIVE",
1001 "IPv6 stack is not active, using IPv4 socket.");
1002 Logger::put(
1003 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1004 MessageLoader::getMessage(parms));
1005 #if defined(PEGASUS_DEBUG)
1006 cout << MessageLoader::getMessage(parms) << endl;
1007 #endif
1008 }
1009 #endif
1010 if (!addIP6Acceptor)
1011 {
1012 addIP4Acceptor = true;
1013 }
1014
1015 // The server HTTP and HTTPS ports are determined via this algorithm:
1016 // 1) If the user explicitly specified a port, use it.
1017 // 2) If the user did not specify a port, get the port from the
1018 // services file.
1019 mike 1.211.2.10 // 3) If no value is specified in the services file, use the IANA WBEM
1020 // default port.
1021 // Note that 2 and 3 are done within the System::lookupPort method
1022 // An empty string from the ConfigManager implies that the user did not
1023 // specify a port.
1024
1025 if (enableHttpConnection)
1026 {
1027 Uint32 portNumberHttp = 0;
1028 String httpPort = configManager->getCurrentValue("httpPort");
1029 if (httpPort == String::EMPTY)
1030 {
1031 //
1032 // Look up the WBEM-HTTP port number
1033 //
1034 portNumberHttp = System::lookupPort(
1035 WBEM_HTTP_SERVICE_NAME, WBEM_DEFAULT_HTTP_PORT);
1036 }
1037 else
1038 {
1039 //
1040 mike 1.211.2.10 // user-specified
1041 //
1042 CString portString = httpPort.getCString();
1043 char* end = 0;
1044 portNumberHttp = strtol(portString, &end, 10);
1045 if (!(end != 0 && *end == '\0'))
1046 {
1047 throw InvalidPropertyValue("httpPort", httpPort);
1048 }
1049 }
1050
1051 if (addIP6Acceptor)
1052 {
1053 _cimServer->addAcceptor(HTTPAcceptor::IPV6_CONNECTION,
1054 portNumberHttp, false);
1055 }
1056 if (addIP4Acceptor)
1057 {
1058 _cimServer->addAcceptor(HTTPAcceptor::IPV4_CONNECTION,
1059 portNumberHttp, false);
1060 }
1061 mike 1.211.2.10
1062 MessageLoaderParms parms(
1063 "src.Server.cimserver.LISTENING_ON_HTTP_PORT",
1064 "Listening on HTTP port $0.", portNumberHttp);
1065 Logger::put(
1066 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1067 MessageLoader::getMessage(parms));
1068 #if defined(PEGASUS_DEBUG)
1069 cout << MessageLoader::getMessage(parms) << endl;
1070 #endif
1071 }
1072
1073 if (enableHttpsConnection)
1074 {
1075 Uint32 portNumberHttps = 0;
1076 String httpsPort = configManager->getCurrentValue("httpsPort");
1077 if (httpsPort == String::EMPTY)
1078 {
1079 //
1080 // Look up the WBEM-HTTPS port number
1081 //
1082 mike 1.211.2.10 portNumberHttps = System::lookupPort(
1083 WBEM_HTTPS_SERVICE_NAME, WBEM_DEFAULT_HTTPS_PORT);
1084 }
1085 else
1086 {
1087 //
1088 // user-specified
1089 //
1090 CString portString = httpsPort.getCString();
1091 char* end = 0;
1092 portNumberHttps = strtol(portString, &end, 10);
1093 if (!(end != 0 && *end == '\0'))
1094 {
1095 throw InvalidPropertyValue("httpsPort", httpsPort);
1096 }
1097 }
1098 if (addIP6Acceptor)
1099 {
1100 _cimServer->addAcceptor(HTTPAcceptor::IPV6_CONNECTION,
1101 portNumberHttps, true);
1102 }
1103 mike 1.211.2.10 if (addIP4Acceptor)
1104 {
1105 _cimServer->addAcceptor(HTTPAcceptor::IPV4_CONNECTION,
1106 portNumberHttps, true);
1107 }
1108 MessageLoaderParms parms(
1109 "src.Server.cimserver.LISTENING_ON_HTTPS_PORT",
1110 "Listening on HTTPS port $0.", portNumberHttps);
1111 Logger::put(
1112 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1113 MessageLoader::getMessage(parms));
1114 #if defined(PEGASUS_DEBUG)
1115 cout << MessageLoader::getMessage(parms) << endl;
1116 #endif
1117 }
1118
1119 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
1120 {
1121 _cimServer->addAcceptor(HTTPAcceptor::LOCAL_CONNECTION, 0, false);
1122
1123 MessageLoaderParms parms(
1124 mike 1.211.2.10 "src.Server.cimserver.LISTENING_ON_LOCAL",
1125 "Listening on local connection socket.");
1126 Logger::put(
1127 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1128 MessageLoader::getMessage(parms));
1129 # if defined(PEGASUS_DEBUG)
1130 cout << MessageLoader::getMessage(parms) << endl;
1131 # endif
1132 }
1133 #endif
1134
1135 _cimServer->bind();
1136
1137 // notify parent process (if there is a parent process) to terminate
1138 // so user knows that there is cimserver ready to serve CIM requests.
1139 if (daemonOption)
1140 {
1141 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1142 Executor::daemonizeExecutor();
1143 #else
1144 _cimServerProcess->notify_parent(0);
1145 mike 1.211.2.10 #endif
1146 }
1147
1148 #if defined(PEGASUS_OS_VXWORKS)
1149 cout << "Started CIM Server." << endl;
1150 #endif
1151
1152 #if defined(PEGASUS_DEBUG)
1153 cout << "Started. " << endl;
1154 #endif
1155
1156 // Put server started message to the logger
1157 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
1158 Logger::INFORMATION,
1159 "src.Server.cimserver.STARTED_VERSION",
1160 "Started $0 version $1.",
1161 _cimServerProcess->getProductName(),
1162 _cimServerProcess->getCompleteVersion());
1163
1164 #if defined(PEGASUS_OS_TYPE_UNIX) && !defined(PEGASUS_OS_ZOS)
1165 if (daemonOption && !debugOutputOption)
1166 mike 1.211.2.10 {
1167 // Direct standard input, output, and error to /dev/null,
1168 // since we are running as a daemon.
1169 close(STDIN_FILENO);
1170 open("/dev/null", O_RDONLY);
1171 close(STDOUT_FILENO);
1172 open("/dev/null", O_RDWR);
1173 close(STDERR_FILENO);
1174 open("/dev/null", O_RDWR);
1175 }
1176 #endif
1177 }
1178 catch (Exception& e)
1179 {
1180 MessageLoaderParms parms("src.Server.cimserver.SERVER_NOT_STARTED",
1181 "cimserver not started: $0", e.getMessage());
1182 Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
1183 MessageLoader::getMessage(parms));
1184 cerr << MessageLoader::getMessage(parms) << endl;
1185
1186 //
1187 mike 1.211.2.10 // notify parent process (if there is a parent process) to terminate
1188 //
1189 if (daemonOption)
1190 _cimServerProcess->notify_parent(1);
1191
1192 deleteCIMServer();
1193 return 1;
1194 }
1195
1196 // Run the main CIM Server loop
1197
1198 try
1199 {
1200 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
1201
1202 // ARM is a z/OS internal restart facility.
1203 // This is a z/OS specific change.
1204
1205 // Instatiating the automatic restart manager for zOS
1206 ARM_zOS automaticRestartManager;
1207
1208 mike 1.211.2.10 // register to zOS ARM
1209 automaticRestartManager.Register();
1210
1211 #endif
1212
1213 //
1214 // Loop to call CIMServer's runForever() method until CIMServer
1215 // has been shutdown
1216 //
1217 while (!_cimServer->terminated())
1218 {
1219 _cimServer->runForever();
1220 }
1221
1222 //
1223 // normal termination
1224 //
1225
1226 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
1227
1228 // ARM is a z/OS internal restart facility.
1229 mike 1.211.2.10 // This is a z/OS specific change.
1230
1231 // register to zOS ARM
1232 automaticRestartManager.DeRegister();
1233
1234 #endif
1235
1236 // Put server shutdown message to the logger
1237 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
1238 Logger::INFORMATION, "src.Server.cimserver.STOPPED",
1239 "$0 stopped.", _cimServerProcess->getProductName());
1240 }
1241 catch (Exception& e)
1242 {
1243 MessageLoaderParms parms(
1244 "src.Server.cimserver.ERROR",
1245 "Error: $0",
1246 e.getMessage());
1247 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
1248 MessageLoader::getMessage(parms));
1249 cerr << MessageLoader::getMessage(parms) << endl;
1250 mike 1.211.2.10
1251 deleteCIMServer();
1252 return 1;
1253 }
1254
1255 deleteCIMServer();
1256 return 0;
1257 }
1258
1259 #if !defined(PEGASUS_BUILDING_CIMSERVER_LIBRARY)
|
1260 kumpf 1.199
|
1261 mike 1.32 int main(int argc, char** argv)
1262 {
|
1263 mike 1.211.2.9 return PegasusServerMain(argc, argv);
|
1264 mike 1.32 }
|
1265 mike 1.211.2.10
1266 #endif /* PEGASUS_BUILDING_CIMSERVER_LIBRARY */
|