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 #if defined(PEGASUS_OS_VXWORKS)
455 /*
456 ATTN-MEB: create constant for this:
457 */
458 // On VxWorks, run cimserver in /ramfs:0 directory:
459 {
|
460 mike 1.211.2.12 const char PATH[] = "/romfs";
|
461 mike 1.211.2.10 if (chdir(PATH) != 0)
462 {
463 fprintf(stderr, "cimserver: failed to chdir to %s\n", PATH);
464 fprintf(stderr, "cimserver: aborting...\n");
465 exit(1);
466 }
467 char cwd[4096];
468 cwd[0] = '\0';
469 getcwd(cwd, sizeof(cwd));
470 printf("Changed directory to \"%s\"\n", cwd);
471 }
472 #endif
473
474 #ifdef PEGASUS_OS_ZOS
475 // Direct standard input to /dev/null,
476 close(STDIN_FILENO);
477 open("/dev/null", O_RDONLY);
478
479 if ( setEBCDICEncoding(STDOUT_FILENO)==-1 ||
480 setEBCDICEncoding(STDERR_FILENO)==-1 )
481 {
482 mike 1.211.2.10 PEG_TRACE_CSTRING(TRC_SERVER,Tracer::LEVEL4,
483 "Coud not set stdout or stderr to EBCDIC encoding.");
484 }
485 // Need to initialize timezone information in the
486 // initial processing thread (IPT)
487 tzset();
488 #endif
489
490 #if defined(PEGASUS_OS_AIX) && defined(PEGASUS_HAS_MESSAGES)
491 setlocale(LC_ALL, "");
492 #endif
493
494 #ifndef PEGASUS_OS_TYPE_WINDOWS
495 //
496 // Get environment variables:
497 //
498 # if defined(PEGASUS_OS_AIX) && defined(PEGASUS_USE_RELEASE_DIRS)
499 pegasusHome = AIX_RELEASE_PEGASUS_HOME;
500 # elif defined(PEGASUS_OS_PASE)
501 const char *tmp = getenv("PEGASUS_HOME");
502 pegasusHome = (tmp == 0) ? PASE_DEFAULT_PEGASUS_HOME : tmp;
503 mike 1.211.2.10 # elif !defined(PEGASUS_USE_RELEASE_DIRS) || \
504 defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
505 const char* tmp = getenv("PEGASUS_HOME");
506
507 if (tmp)
508 {
509 pegasusHome = tmp;
510 }
511 # endif
512
513 FileSystem::translateSlashes(pegasusHome);
514 #else
515
516 // windows only
517 //setHome(pegasusHome);
518 pegasusHome = _cimServerProcess->getHome();
519 #endif
520
521 #ifdef PEGASUS_ENABLE_PRIVILEGE_SEPARATION
522
523 // If invoked with "--executor-socket <socket>" option, then use executor.
524 mike 1.211.2.10
525 Executor::setSock(_extractExecutorSockOpt(argc, argv));
526
527 // Ping executor to verify the specified socket is valid.
528
529 if (Executor::ping() != 0)
530 {
531 MessageLoaderParms parms("src.Server.cimserver.EXECUTOR_PING_FAILED",
532 "Failed to ping the executor on the specified socket.");
533 cerr << argv[0] << ": " << MessageLoader::getMessage(parms) << endl;
534 exit(1);
535 }
536
537 #endif /* !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION) */
538
539 // Get help, version, and shutdown options
540
541 for (int i = 1; i < argc; )
542 {
543 const char* arg = argv[i];
544 if (String::equal(arg,"--help"))
545 mike 1.211.2.10 {
546 PrintHelp(argv[0]);
547 exit(0);
548 }
549 else if (String::equal(arg,"--version"))
550 {
551 cout << _cimServerProcess->getCompleteVersion() << endl;
552 exit(0);
553 }
554 // Check for -option
555 else if (*arg == '-')
556 {
557 // Get the option
558 const char* option = arg + 1;
559
560 //
561 // Check to see if user asked for the version (-v option):
562 //
563 if (*option == OPTION_VERSION &&
564 strlen(option) == 1)
565 {
566 mike 1.211.2.10 cout << _cimServerProcess->getCompleteVersion() << endl;
567 exit(0);
568 }
569 //
570 // Check to see if user asked for help (-h option):
571 //
572 else if (*option == OPTION_HELP &&
573 (strlen(option) == 1))
574 {
575 PrintHelp(argv[0]);
576 exit(0);
577 }
578 #if !defined(PEGASUS_USE_RELEASE_DIRS)
579 else if (*option == OPTION_HOME &&
580 (strlen(option) == 1))
581 {
582 if (i + 1 < argc)
583 {
584 pegasusHome.assign(argv[i + 1]);
585 }
586 else
587 mike 1.211.2.10 {
588 String opt(option);
589 MessageLoaderParms parms(
590 "src.Server.cimserver.MISSING_ARGUMENT",
591 "Missing argument for option -$0",
592 opt);
593 cout << MessageLoader::getMessage(parms) << endl;
594 exit(0);
595 }
596
597 memmove(&argv[i], &argv[i + 2], (argc-i-1) * sizeof(char*));
598 argc -= 2;
599 }
600 #endif
601 //
602 // Check to see if user asked for debug output (-X option):
603 //
604 else if (*option == OPTION_DEBUGOUTPUT &&
605 (strlen(option) == 1))
606 {
607 MessageLoaderParms parms(
608 mike 1.211.2.10 "src.Server.cimserver.UNSUPPORTED_DEBUG_OPTION",
609 "Unsupported debug output option is enabled.");
610 cout << MessageLoader::getMessage(parms) << endl;
611
612 debugOutputOption = true;
613
614 #if defined(PEGASUS_OS_HPUX)
615 System::bindVerbose = true;
616 #endif
617
618 // remove the option from the command line
619 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
620 argc--;
621 }
622 //
623 // Check to see if user asked for shutdown (-s option):
624 //
625 else if (*option == OPTION_SHUTDOWN &&
626 (strlen(option) == 1))
627 {
628 //
629 mike 1.211.2.10 // Check to see if shutdown has already been specified:
630 //
631 if (shutdownOption)
632 {
633 MessageLoaderParms parms(
634 "src.Server.cimserver.DUPLICATE_SHUTDOWN_OPTION",
635 "Duplicate shutdown option specified.");
636
637 cout << MessageLoader::getMessage(parms) << endl;
638 exit(0);
639 }
640
641 shutdownOption = true;
642
643 // remove the option from the command line
644 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
645 argc--;
646 }
647 else
648 i++;
649 }
650 mike 1.211.2.10 else
651 i++;
652 }
653
654 //
655 // Set the value for pegasusHome property
656 //
657 ConfigManager::setPegasusHome(pegasusHome);
658
659 //
660 // Do the platform specific run
661 //
662
663 return _cimServerProcess->platform_run(
664 argc, argv, shutdownOption, debugOutputOption);
665 }
666
667 void CIMServerProcess::cimserver_stop()
668 {
669 _cimServer->shutdownSignal();
670 }
671 mike 1.211.2.10
672 //
673 // The main, common, running code
674 //
675 // NOTE: Do NOT call exit(). Use return(), otherwise some platforms
676 // will fail to shutdown properly/cleanly.
677 //
678 // TODO: Current change minimal for platform "service" shutdown bug fixes.
679 // Perhaps further extract out common stuff and put into main(), put
680 // daemon stuff into platform specific platform_run(), etc.
681 // Note: make sure to not put error handling stuff that platform
682 // specific runs may need to deal with better (instead of exit(), etc).
683 //
684
685 int CIMServerProcess::cimserver_run(
686 int argc,
687 char** argv,
688 Boolean shutdownOption,
689 Boolean debugOutputOption)
690 {
691 Boolean daemonOption = false;
692 mike 1.211.2.10
693 #if defined (PEGASUS_OS_PASE) && !defined (PEGASUS_DEBUG)
694 // PASE have itself regular for checking privileged user
695 if (!System::isPrivilegedUser("*CURRENT "))
696 {
697 MessageLoaderParms parms(
698 "src.Server.cimserver.NO_AUTHORITY.PEGASUS_OS_PASE",
699 "The caller should be a privileged user,"
700 " or the server will not run.");
701 cerr << MessageLoader::getMessage(parms) << endl;
702 exit (1);
703 }
704 char jobName[11];
705 // this function only can be found in PASE environment
706 umeGetJobName(jobName, false);
707 if (strncmp("QUMECIMOM ", jobName, 10) != 0
708 && strncmp("QUMEENDCIM", jobName, 10) != 0)
709 {
710 MessageLoaderParms parms(
711 "src.Server.cimserver.NOT_OFFICIAL_START.PEGASUS_OS_PASE",
712 "cimserver can not be started by user.\nServer will not run.");
713 mike 1.211.2.10 cerr << MessageLoader::getMessage(parms) << endl;
714 exit (1);
715 }
716
717 // Direct standard input, output, and error to /dev/null,
718 // PASE run this job in background, any output in not allowed
719 freopen("/dev/null", "r", stdin);
720 freopen("/dev/null", "w", stdout);
721 freopen("/dev/null", "w", stderr);
722 #endif
723
724 //
725 // Get an instance of the Config Manager.
726 //
727 ConfigManager* configManager = ConfigManager::getInstance();
728
729 #if !defined(PEGASUS_OS_VXWORKS)
730 configManager->useConfigFiles = true;
731 #endif
732
733 try
734 mike 1.211.2.10 {
735 //
736 // Get options (from command line and from configuration file); this
737 // removes corresponding options and their arguments from the command
738 // line. NOTE: If shutdownOption=true, the contents of current config
739 // file are not overwritten by the planned config file.
740 //
741 GetOptions(configManager, argc, argv, shutdownOption);
742
743 //
744 // Initialize the message home directory in the MessageLoader.
745 // This is the default directory where the resource bundles are found.
746 //
747 MessageLoader::setPegasusMsgHome(ConfigManager::getHomedPath(
748 ConfigManager::getInstance()->getCurrentValue("messageDir")));
749
750 #ifdef PEGASUS_OS_PASE
751 // set ccsid to unicode for entire job
752 // ccsid is globolization mechanism in PASE environment
753 if (_SETCCSID(1208) == -1)
754 {
755 mike 1.211.2.10 MessageLoaderParms parms(
756 "src.Server.cimserver.SET_CCSID_ERROR.PEGASUS_OS_PASE",
757 "Failed to set CCSID, server will stop.");
758 cerr << MessageLoader::getMessage(parms) << endl;
759 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::FATAL,
760 "src.Server.cimserver.SET_CCSID_ERROR.PEGASUS_OS_PASE",
761 "Failed to set CCSID, server will stop.\n");
762 exit (1);
763 }
764
765 char fullJobName[29];
766 umeGetJobName(fullJobName, true);
767 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
768 "src.Server.cimserver.SERVER_JOB_NAME.PEGASUS_OS_PASE",
769 "CIM Server's Job Name is: $0", fullJobName);
770 #endif
771
772 Boolean enableHttpConnection = ConfigManager::parseBooleanValue(
773 configManager->getCurrentValue("enableHttpConnection"));
774 Boolean enableHttpsConnection = ConfigManager::parseBooleanValue(
775 configManager->getCurrentValue("enableHttpsConnection"));
776 mike 1.211.2.10
777 // Make sure at least one connection is enabled
778 #ifdef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
779 if (!enableHttpConnection && !enableHttpsConnection)
780 {
781 //l10n
782 //Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
783 //"Neither HTTP nor HTTPS connection is enabled. "
784 //"CIMServer will not be started.");
785 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
786 "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
787 "Neither HTTP nor HTTPS connection is enabled."
788 " CIMServer will not be started.");
789 //cerr << "Neither HTTP nor HTTPS connection is enabled. "
790 //"CIMServer will not be started." << endl;
791 MessageLoaderParms parms(
792 "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
793 "Neither HTTP nor HTTPS connection is enabled."
794 " CIMServer will not be started.");
795 cerr << MessageLoader::getMessage(parms) << endl;
796 return(1);
797 mike 1.211.2.10 }
798 #endif
799 //
800 // Check to see if we should start Pegasus as a daemon
801 //
802
803 daemonOption = ConfigManager::parseBooleanValue(
804 configManager->getCurrentValue("daemon"));
805
806 #if !defined(PEGASUS_USE_SYSLOGS)
807 String logsDirectory = ConfigManager::getHomedPath(
808 configManager->getCurrentValue("logdir"));
809
810 // Set up the Logger. This does not open the logs.
811 // Might be more logical to clean before set.
812 Logger::setHomeDirectory(logsDirectory);
813
814 # ifdef PEGASUS_OS_PASE
815 /* write job log to tell where pegasus log is.*/
816 if(logsDirectory.size() > 0)
817 // this function only can be found in PASE environment
818 mike 1.211.2.10 logPegasusDir2joblog(logsDirectory.getCString());
819 else
820 logPegasusDir2joblog(".");
821 # endif
822 #endif
823
|
824 mike 1.211.2.13 //
825 // Some platforms do not support using client to shutdown server.
826 //
827 #if !defined(PEGASUS_REMOVE_SERVER_CLIENT_USAGE)
|
828 mike 1.211.2.10 //
829 // Check to see if we need to shutdown CIMOM
830 //
831 if (shutdownOption)
832 {
833 String configTimeout =
834 configManager->getCurrentValue("shutdownTimeout");
835 Uint32 timeoutValue =
836 strtol(configTimeout.getCString(), (char **)0, 10);
|
837 mike 1.211.2.13 # ifdef PEGASUS_SLP_REG_TIMEOUT
|
838 mike 1.211.2.10 // To deregister Pegasus with SLP
839 unregisterPegasusFromSLP();
|
840 mike 1.211.2.13 # endif
|
841 mike 1.211.2.10
842 ServerShutdownClient serverShutdownClient(&_serverRunStatus);
843 serverShutdownClient.shutdown(timeoutValue);
844
845 MessageLoaderParms parms(
846 "src.Server.cimserver.SERVER_STOPPED",
847 "CIM Server stopped.");
848
849 cout << MessageLoader::getMessage(parms) << endl;
850 return 0;
851 }
|
852 mike 1.211.2.13 #endif /* PEGASUS_REMOVE_SERVER_CLIENT_USAGE */
|
853 mike 1.211.2.10
854 #if defined(PEGASUS_DEBUG) && !defined(PEGASUS_USE_SYSLOGS)
855 // Leave this in until people get familiar with the logs.
856 MessageLoaderParms parms("src.Server.cimserver.LOGS_DIRECTORY",
857 "Logs Directory = ");
858 cout << MessageLoader::getMessage(parms) << logsDirectory << endl;
859 #endif
860 }
861 catch (Exception& e)
862 {
863 MessageLoaderParms parms("src.Server.cimserver.SERVER_NOT_STARTED",
864 "cimserver not started: $0", e.getMessage());
865 Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
866 MessageLoader::getMessage(parms));
867 cerr << MessageLoader::getMessage(parms) << endl;
868
869 return 1;
870 }
871
872 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) && defined(PEGASUS_ZOS_SECURITY)
873 startupCheckBPXServer(true);
874 mike 1.211.2.10 startupCheckProfileCIMSERVclassWBEM();
875 startupEnableMSC();
876 #endif
877
878 #if defined(PEGASUS_DEBUG)
879 // Put out startup up message.
880 cout << _cimServerProcess->getProductName() << " " <<
881 _cimServerProcess->getCompleteVersion() << endl;
882 #endif
883
884 // reset message loading to NON-process locale
885 MessageLoader::_useProcessLocale = false;
886
887 // Get the parent's PID before forking
888 _serverRunStatus.setParentPid(System::getPID());
889
890 // Do not fork when using privilege separation (executor will daemonize
891 // itself later).
892 if (daemonOption)
893 {
894 if (-1 == _cimServerProcess->cimserver_fork())
895 mike 1.211.2.10 return -1;
896 }
897
898 // Now we are after the fork...
899 // Create a dummy Thread object that can be used to store the
900 // AcceptLanguageList object for CIM requests that are serviced
901 // by this thread (initial thread of server). Need to do this
902 // because this thread is not in a ThreadPool, but is used
903 // to service CIM requests.
904 // The run function for the dummy Thread should never be called,
905 dummyInitialThread = new Thread(dummyThreadFunc, NULL, false);
906 Thread::setCurrent(dummyInitialThread);
907 AcceptLanguageList default_al;
908 try
909 {
910 default_al = LanguageParser::getDefaultAcceptLanguages();
911 Thread::setLanguages(new AcceptLanguageList(default_al));
912 }
913 catch (InvalidAcceptLanguageHeader& e)
914 {
915 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
916 mike 1.211.2.10 "src.Server.cimserver.FAILED_TO_SET_PROCESS_LOCALE",
917 "Could not convert the system process locale into a valid "
918 "AcceptLanguage format.");
919 Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
920 e.getMessage());
921 }
922
923 #if !defined(PEGASUS_OS_TYPE_WINDOWS) && !defined(PEGASUS_OS_VXWORKS)
924 umask(S_IRWXG|S_IRWXO);
925 #endif
926
927 // Start up the CIM Server
928
929 try
930 {
|
931 karl 1.211.2.11 #if defined(PEGASUS_OS_TYPE_UNIX)
932
933 // ATTN KS This file not used for VxWorks
|
934 mike 1.211.2.10 //
935 // Lock the CIMSERVER_LOCK_FILE during CIM Server start-up to prevent
936 // concurrent writes to this file by multiple cimserver processes
937 // starting at the same time.
938 //
939 CString startupLockFileName = ConfigManager::getHomedPath(
940 PEGASUS_CIMSERVER_START_LOCK_FILE).getCString();
941
942 // Make sure the start-up lock file exists
943 FILE* startupLockFile;
944 if ((startupLockFile = fopen(startupLockFileName, "w")) != 0)
945 {
946 fclose(startupLockFile);
947 }
948
949 AutoFileLock fileLock(startupLockFileName);
950 #endif
951
952 #if defined(PEGASUS_OS_TYPE_UNIX) || \
953 defined(PEGASUS_OS_VMS) || \
954 defined(PEGASUS_OS_VXWORKS)
955 mike 1.211.2.10 //
956 // Check if a CIM Server is already running. If so, print an error
957 // message and notify the parent process (if there is one) to terminate
958 //
959 if (_serverRunStatus.isServerRunning())
960 {
961 MessageLoaderParms parms(
962 "src.Server.cimserver.UNABLE_TO_START_SERVER_ALREADY_RUNNING",
963 "Unable to start CIMServer. CIMServer is already running.");
964 Logger::put(
965 Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
966 MessageLoader::getMessage(parms));
967 cerr << MessageLoader::getMessage(parms) << endl;
968
969 if (daemonOption)
970 {
971 _cimServerProcess->notify_parent(1);
972 }
973
974 return 1;
975 }
976 mike 1.211.2.10
977 //
978 // Declare ourselves as the running CIM Server process, and write our
979 // PID to the PID file.
980 //
981 _serverRunStatus.setServerRunning();
982 #endif
983
984 // Create and initialize the CIMServer object
985
986 _cimServer = new CIMServer();
987
988 Boolean enableHttpConnection = ConfigManager::parseBooleanValue(
989 configManager->getCurrentValue("enableHttpConnection"));
990 Boolean enableHttpsConnection = ConfigManager::parseBooleanValue(
991 configManager->getCurrentValue("enableHttpsConnection"));
992
993 #ifdef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
994 // Make sure at least one connection is enabled
995 if (!enableHttpConnection && !enableHttpsConnection)
996 {
997 mike 1.211.2.10 MessageLoaderParms parms(
998 "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
999 "Neither HTTP nor HTTPS connection is enabled.");
1000 throw Exception(parms);
1001 }
1002 #endif
1003
1004 Boolean addIP6Acceptor = false;
1005 Boolean addIP4Acceptor = false;
1006
1007 #ifdef PEGASUS_OS_TYPE_WINDOWS
1008 addIP4Acceptor = true;
1009 #endif
1010
1011 #ifdef PEGASUS_ENABLE_IPV6
1012 // If IPv6 stack is disabled swicth to IPv4 stack.
1013 if (System::isIPv6StackActive())
1014 {
1015 addIP6Acceptor = true;
1016 }
1017 else
1018 mike 1.211.2.10 {
1019 MessageLoaderParms parms(
1020 "src.Server.cimserver.IPV6_STACK_NOT_ACTIVE",
1021 "IPv6 stack is not active, using IPv4 socket.");
1022 Logger::put(
1023 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1024 MessageLoader::getMessage(parms));
1025 #if defined(PEGASUS_DEBUG)
1026 cout << MessageLoader::getMessage(parms) << endl;
1027 #endif
1028 }
1029 #endif
1030 if (!addIP6Acceptor)
1031 {
1032 addIP4Acceptor = true;
1033 }
1034
1035 // The server HTTP and HTTPS ports are determined via this algorithm:
1036 // 1) If the user explicitly specified a port, use it.
1037 // 2) If the user did not specify a port, get the port from the
1038 // services file.
1039 mike 1.211.2.10 // 3) If no value is specified in the services file, use the IANA WBEM
1040 // default port.
1041 // Note that 2 and 3 are done within the System::lookupPort method
1042 // An empty string from the ConfigManager implies that the user did not
1043 // specify a port.
1044
1045 if (enableHttpConnection)
1046 {
1047 Uint32 portNumberHttp = 0;
1048 String httpPort = configManager->getCurrentValue("httpPort");
1049 if (httpPort == String::EMPTY)
1050 {
1051 //
1052 // Look up the WBEM-HTTP port number
1053 //
1054 portNumberHttp = System::lookupPort(
1055 WBEM_HTTP_SERVICE_NAME, WBEM_DEFAULT_HTTP_PORT);
1056 }
1057 else
1058 {
1059 //
1060 mike 1.211.2.10 // user-specified
1061 //
1062 CString portString = httpPort.getCString();
1063 char* end = 0;
1064 portNumberHttp = strtol(portString, &end, 10);
1065 if (!(end != 0 && *end == '\0'))
1066 {
1067 throw InvalidPropertyValue("httpPort", httpPort);
1068 }
1069 }
1070
1071 if (addIP6Acceptor)
1072 {
1073 _cimServer->addAcceptor(HTTPAcceptor::IPV6_CONNECTION,
1074 portNumberHttp, false);
1075 }
1076 if (addIP4Acceptor)
1077 {
1078 _cimServer->addAcceptor(HTTPAcceptor::IPV4_CONNECTION,
1079 portNumberHttp, false);
1080 }
1081 mike 1.211.2.10
1082 MessageLoaderParms parms(
1083 "src.Server.cimserver.LISTENING_ON_HTTP_PORT",
1084 "Listening on HTTP port $0.", portNumberHttp);
1085 Logger::put(
1086 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1087 MessageLoader::getMessage(parms));
1088 #if defined(PEGASUS_DEBUG)
1089 cout << MessageLoader::getMessage(parms) << endl;
1090 #endif
1091 }
1092
1093 if (enableHttpsConnection)
1094 {
1095 Uint32 portNumberHttps = 0;
1096 String httpsPort = configManager->getCurrentValue("httpsPort");
1097 if (httpsPort == String::EMPTY)
1098 {
1099 //
1100 // Look up the WBEM-HTTPS port number
1101 //
1102 mike 1.211.2.10 portNumberHttps = System::lookupPort(
1103 WBEM_HTTPS_SERVICE_NAME, WBEM_DEFAULT_HTTPS_PORT);
1104 }
1105 else
1106 {
1107 //
1108 // user-specified
1109 //
1110 CString portString = httpsPort.getCString();
1111 char* end = 0;
1112 portNumberHttps = strtol(portString, &end, 10);
1113 if (!(end != 0 && *end == '\0'))
1114 {
1115 throw InvalidPropertyValue("httpsPort", httpsPort);
1116 }
1117 }
1118 if (addIP6Acceptor)
1119 {
1120 _cimServer->addAcceptor(HTTPAcceptor::IPV6_CONNECTION,
1121 portNumberHttps, true);
1122 }
1123 mike 1.211.2.10 if (addIP4Acceptor)
1124 {
1125 _cimServer->addAcceptor(HTTPAcceptor::IPV4_CONNECTION,
1126 portNumberHttps, true);
1127 }
1128 MessageLoaderParms parms(
1129 "src.Server.cimserver.LISTENING_ON_HTTPS_PORT",
1130 "Listening on HTTPS port $0.", portNumberHttps);
1131 Logger::put(
1132 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1133 MessageLoader::getMessage(parms));
1134 #if defined(PEGASUS_DEBUG)
1135 cout << MessageLoader::getMessage(parms) << endl;
1136 #endif
1137 }
1138
1139 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
1140 {
1141 _cimServer->addAcceptor(HTTPAcceptor::LOCAL_CONNECTION, 0, false);
1142
1143 MessageLoaderParms parms(
1144 mike 1.211.2.10 "src.Server.cimserver.LISTENING_ON_LOCAL",
1145 "Listening on local connection socket.");
1146 Logger::put(
1147 Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
1148 MessageLoader::getMessage(parms));
1149 # if defined(PEGASUS_DEBUG)
1150 cout << MessageLoader::getMessage(parms) << endl;
1151 # endif
1152 }
1153 #endif
1154
1155 _cimServer->bind();
1156
1157 // notify parent process (if there is a parent process) to terminate
1158 // so user knows that there is cimserver ready to serve CIM requests.
1159 if (daemonOption)
1160 {
1161 #if defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)
1162 Executor::daemonizeExecutor();
1163 #else
1164 _cimServerProcess->notify_parent(0);
1165 mike 1.211.2.10 #endif
1166 }
1167
1168 #if defined(PEGASUS_OS_VXWORKS)
1169 cout << "Started CIM Server." << endl;
1170 #endif
1171
1172 #if defined(PEGASUS_DEBUG)
1173 cout << "Started. " << endl;
1174 #endif
1175
1176 // Put server started message to the logger
1177 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
1178 Logger::INFORMATION,
1179 "src.Server.cimserver.STARTED_VERSION",
1180 "Started $0 version $1.",
1181 _cimServerProcess->getProductName(),
1182 _cimServerProcess->getCompleteVersion());
1183
1184 #if defined(PEGASUS_OS_TYPE_UNIX) && !defined(PEGASUS_OS_ZOS)
1185 if (daemonOption && !debugOutputOption)
1186 mike 1.211.2.10 {
1187 // Direct standard input, output, and error to /dev/null,
1188 // since we are running as a daemon.
1189 close(STDIN_FILENO);
1190 open("/dev/null", O_RDONLY);
1191 close(STDOUT_FILENO);
1192 open("/dev/null", O_RDWR);
1193 close(STDERR_FILENO);
1194 open("/dev/null", O_RDWR);
1195 }
1196 #endif
1197 }
1198 catch (Exception& e)
1199 {
1200 MessageLoaderParms parms("src.Server.cimserver.SERVER_NOT_STARTED",
1201 "cimserver not started: $0", e.getMessage());
1202 Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
1203 MessageLoader::getMessage(parms));
1204 cerr << MessageLoader::getMessage(parms) << endl;
1205
1206 //
1207 mike 1.211.2.10 // notify parent process (if there is a parent process) to terminate
1208 //
1209 if (daemonOption)
1210 _cimServerProcess->notify_parent(1);
1211
1212 deleteCIMServer();
1213 return 1;
1214 }
1215
1216 // Run the main CIM Server loop
1217
1218 try
1219 {
1220 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
1221
1222 // ARM is a z/OS internal restart facility.
1223 // This is a z/OS specific change.
1224
1225 // Instatiating the automatic restart manager for zOS
1226 ARM_zOS automaticRestartManager;
1227
1228 mike 1.211.2.10 // register to zOS ARM
1229 automaticRestartManager.Register();
1230
1231 #endif
1232
1233 //
1234 // Loop to call CIMServer's runForever() method until CIMServer
1235 // has been shutdown
1236 //
1237 while (!_cimServer->terminated())
1238 {
1239 _cimServer->runForever();
1240 }
1241
1242 //
1243 // normal termination
1244 //
1245
1246 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
1247
1248 // ARM is a z/OS internal restart facility.
1249 mike 1.211.2.10 // This is a z/OS specific change.
1250
1251 // register to zOS ARM
1252 automaticRestartManager.DeRegister();
1253
1254 #endif
1255
1256 // Put server shutdown message to the logger
1257 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
1258 Logger::INFORMATION, "src.Server.cimserver.STOPPED",
1259 "$0 stopped.", _cimServerProcess->getProductName());
1260 }
1261 catch (Exception& e)
1262 {
1263 MessageLoaderParms parms(
1264 "src.Server.cimserver.ERROR",
1265 "Error: $0",
1266 e.getMessage());
1267 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
1268 MessageLoader::getMessage(parms));
1269 cerr << MessageLoader::getMessage(parms) << endl;
1270 mike 1.211.2.10
1271 deleteCIMServer();
1272 return 1;
1273 }
1274
1275 deleteCIMServer();
1276 return 0;
1277 }
1278
1279 #if !defined(PEGASUS_BUILDING_CIMSERVER_LIBRARY)
|
1280 kumpf 1.199
|
1281 mike 1.32 int main(int argc, char** argv)
1282 {
|
1283 mike 1.211.2.9 return PegasusServerMain(argc, argv);
|
1284 mike 1.32 }
|
1285 mike 1.211.2.10
1286 #endif /* PEGASUS_BUILDING_CIMSERVER_LIBRARY */
|