예제 #1
0
파일: Pulsar.cpp 프로젝트: daedalus/iometer
int CDECL main(int argc, char *argv[])
{
	Manager *manager;
	char iometer[MAX_NETWORK_NAME];
	int error = 0;
	// struct dynamo_param param; //move up to global scope

#if defined(IOMTR_OS_LINUX)
	struct aioinit aioDefaults;

	memset(&aioDefaults, 0, sizeof(aioDefaults));
	aioDefaults.aio_threads = 32;
	aio_init(&aioDefaults);
	kstatfd = InitIoctlInterface();
#if defined(IOMTR_CPU_XSCALE)
	if ((ccntfd = InitCCNTInterface()) < 0) {
		exit(1);
	}
#endif
#endif

	Banner();

#if !defined(DO_NOT_PARSE_BEFORE_MANAGER)
	// In order to allow command line parameters to influence default values of
	// the Manager class members, we need to parse parameters before instantiating
	// the Manager, but to do this, we need to:

	// Setup local storage -- could just be in the global param structure???
	char blkdevlist[MAX_TARGETS][MAX_NAME];
	char manager_name[MAX_WORKER_NAME];
	char network_name[MAX_NETWORK_NAME];
	char exclude_filesys[MAX_EXCLUDE_FILESYS];

	// Init the local storage to match the original code
	iometer[0] = 0;
	manager_name[0] = 0;
	exclude_filesys[0] = 0;
	network_name[0] = 0;

	// Setup the param structure to defaults and to point to buffers above
	param.iometer = iometer;
	param.manager_name = manager_name;
	param.manager_computer_name = network_name;
	param.manager_exclude_fs = exclude_filesys;
	param.blkdevlist = &blkdevlist;
	param.login_port_number = 0;
	param.cpu_affinity = 0; // not specified or default
	param.timer_type = TIMER_UNDEFINED; // use the default
	param.disk_control = RAWDISK_VIEW_NOPART; // do not show raw disks with partitions

	// The manager's GetVersionString method is not available yet since it does not exist, 
	// so we do away with the variable and have ParseParam rely directly on the source of 
	// the strings in ioversion.h. Not too clean but functional...
	// g_pVersionStringWithDebug = NULL; // not needed

	// Parse params and then instantiate the manager next...
	ParseParam(argc, argv, &param);
#endif

	manager = new Manager;

#if !defined(DO_NOT_PARSE_BEFORE_MANAGER)
	// Restore the param globals retrieved above back to the manager
	// since the manager buffers were not available prior to the parse call.
	memcpy(manager->manager_name, manager_name, sizeof(manager_name));
	memcpy(manager->prt->network_name, network_name, sizeof(network_name));
	memcpy(manager->exclude_filesys, exclude_filesys, sizeof(exclude_filesys));
	memcpy(manager->blkdevlist, blkdevlist, sizeof(blkdevlist));
#else // defined(DO_NOT_PARSE_BEFORE_MANAGER) // the original code
	iometer[0] = 0;
	manager->manager_name[0] = 0;
	manager->exclude_filesys[0] = 0;

	//provide a temporary global ptr to the version string for Syntax() to use
	g_pVersionStringWithDebug = manager->GetVersionString(TRUE);

	param.iometer = iometer;
	param.manager_name = manager->manager_name;
	param.manager_computer_name = manager->prt->network_name;
	param.manager_exclude_fs = manager->exclude_filesys;
	param.blkdevlist = &manager->blkdevlist;
	param.login_port_number = 0;
	param.cpu_affinity = 0; // not specified or default
	param.timer_type = TIMER_UNDEFINED; // use the default
	param.disk_control = RAWDISK_VIEW_NOPART; // do not show raw disks with partitions

	ParseParam(argc, argv, &param);

	g_pVersionStringWithDebug = NULL;	//should use manager object after this...
#endif

	iomtr_set_cpu_affinity(param.cpu_affinity);

	// If there were command line parameters, indicate that they were recognized.
	if (iometer[0] || manager->manager_name[0]) {
		cout << "\nCommand line parameter(s):" << endl;

		if (iometer[0]) {
			cout << "   Looking for Iometer on \"" << iometer << "\"" << endl;
		}
		if (manager->manager_name[0]) {
			cout << "   New manager name is \"" << manager->manager_name << "\"" << endl;
		}
	}
	if (manager->exclude_filesys[0]) {
		cout << "\nExcluding the following filesystem types:" << endl;
		cout << "   \"" << manager->exclude_filesys << "\"" << endl;
	} else {
		strcpy(manager->exclude_filesys, DEFAULT_EXCLUDE_FILESYS);
	}
	// cout << endl;

#if defined(IOMTR_OSFAMILY_UNIX)
#if defined(IOMTR_OS_LINUX) || defined(IOMTR_OS_OSX)
	signal(SIGALRM, SIG_IGN);
#elif defined(IOMTR_OS_SOLARIS)
	sigignore(SIGALRM);
#else
#warning ===> WARNING: You have to do some coding here to get the port done!
#endif

	// Initialize the lock on UNIX platforms.
	if (pthread_mutex_init(&lock_mt, NULL)) {
		cout << "unable to init the lock" << endl;
		error = 1;
		goto CleanUp;
		//exit(1);
	}
	// Block SIGPIPE signal. Needed to ensure that Network worker
	// threads don't exit due to a broken pipe signal.
	sigset_t sigset;

	sigemptyset(&sigset);
	sigaddset(&sigset, SIGPIPE);
	if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) {
		cout << "sigprocmask() call failed." << endl;
		cout << "dynamo could be unstable" << endl;
	}
	//
	// the number of file descriptors a process may create can be a small value like 64.
	//
	struct rlimit rlimitp;

	if (getrlimit(RLIMIT_NOFILE, &rlimitp) < 0) {
		cout << "error " << errno << " trying to get rlimit (# file descriptors)" << endl;
	} else {
		// it succeeded. We leave out atleast 25 file descriptors for non-targets
		// and compare with the hard limit.
		unsigned int targets = MAX_TARGETS + 25;

		if (rlimitp.rlim_max < targets) {
			cout << "Only " << rlimitp.rlim_max << " file descriptors available" << endl;
			rlimitp.rlim_cur = rlimitp.rlim_max;
		} else {
			// set the soft limit to the required value.
			rlimitp.rlim_cur = targets;
		}
		if (setrlimit(RLIMIT_NOFILE, &rlimitp) < 0) {
			cout << "error " << errno << " trying to set rlimit (# file descriptors)" << endl;
		}
	}

	// Check for super-user permissions. If not super-user, we
	// cannot get many of the info from the kernel.
	if (getuid() || geteuid()) {
		cout << "Dynamo not running as super-user." << endl;
		cout << "       All available disks might not be reported " << endl;
		cout << "       Cannot get TCP statistics from the kernel " << endl;
	}
#ifdef IOMTR_SETTING_OVERRIDE_FS
	// No command line args specifies destructive testing. Check to see if there
	// are any environment variables specifying the same. We need to warn the user.
	if (getenv("IOMTR_SETTING_OVERRIDE_FS") != NULL) {
		cout << "       ************ WARNING **************" << endl;
		cout << "       dynamo running in Destructive mode." << endl;
		cout << "         (overriding the not mounted fs)" << endl;
		cout << "       ************ WARNING **************" << endl;
	}
#endif				// IOMTR_SETTING_OVERRIDE_FS
#endif				// IOMTR_OSFAMILY_UNIX
#if defined(IOMTR_OSFAMILY_NETWARE)
	// Initialize the lock on NetWare platforms.
	if (pthread_mutex_init(&lock_mt, NULL)) {
		cout << "unable to init the lock" << endl;
		error = 1;
		goto CleanUp;
		//exit(1);
	}
#endif

#if defined(IOMTR_OSFAMILY_WINDOWS)
	// IOmeter/Dynamo now utilizes Windows UAC for privilege elevation,
	// but on version of Windows in which that is not supported we
	// match the UNIX output above.

	BOOL bReturned;
	SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
	PSID AdminGroup; 

	bReturned = AllocateAndInitializeSid(
		&NtAuthority,
		2,
		SECURITY_BUILTIN_DOMAIN_RID,
		DOMAIN_ALIAS_RID_ADMINS,
		0, 0, 0, 0, 0, 0,
		&AdminGroup); 

	if(bReturned) 
	{
		CheckTokenMembership( NULL, AdminGroup, &bReturned);

		if (!bReturned)
		{
			cout << "Dynamo not running as an administrator." << endl;
			cout << "       All available disks might not be reported " << endl;
			cout << endl;
		} 
		FreeSid(AdminGroup); 
	}
#endif

	// Ensure, that the endian type of the CPU is detectable
	if ((IsBigEndian() != 0) && (IsBigEndian() != 1)) {
		cout << "===> ERROR: Endian type of the CPU couldn't be detected." << endl;
		cout << "     [main() in " << __FILE__ << " line " << __LINE__ << "]" << endl;
		error = 1;
		goto CleanUp;
		//exit(1);
	}
	// Entering infinite loop to allow Dynamo to run multiple tests.  Outer while loop allows
	// Dynamo to be reset from Iometer.  If everything works smoothly, resets should be rare.
	while (TRUE) {
		// Initializing worker and logging into Iometer director.
		if (!manager->Login(iometer, param.login_port_number))
			break;

		// Manager will continue to run until an error, or stopped by Iometer.
		if (!manager->Run())
			break;	// Stop running when the manager is done.
	}
	cout << "Ending execution." << endl;
	Sleep(1000);

#if defined(IOMTR_OS_LINUX)
	CleanupIoctlInterface(kstatfd);
#if defined(IOMTR_CPU_XSCALE)
	CleanupCCNTInterface(ccntfd);
#endif
#endif

	//return (0);

CleanUp:
	if (manager) delete manager;
	if (error) exit(error);
	return (0);
}
예제 #2
0
int CDECL main( int argc, char *argv[] )
{
	Manager	manager;
	char	iometer[MAX_NETWORK_NAME];
	struct dynamo_param param;

#if defined(IOMTR_OS_LINUX)
	struct aioinit aioDefaults;

	memset(&aioDefaults, 0, sizeof(aioDefaults));
	aioDefaults.aio_threads = 2;
	aioDefaults.aio_threads = 2;
	aio_init(&aioDefaults);
	kstatfd = InitIoctlInterface();
	procstatstyle = DetectProcStatStyle();
	if (kstatfd < 0 && procstatstyle == -1) {
		cerr << "IoMeter can not get correct status information" << endl;
		exit(1);
	}
#if defined(IOMTR_CPU_XSCALE)
	if ((ccntfd = InitCCNTInterface()) < 0) {
		exit(1);
	}
#endif
#endif

	iometer[0]                 = 0;
	manager.manager_name[0]    = 0;
	manager.exclude_filesys[0] = 0;

	//provide a temporary global ptr to the version string for Syntax() to use
	g_pVersionStringWithDebug = manager.GetVersionString(TRUE);
	
	param.iometer 		    = iometer;
	param.manager_name 	    = manager.manager_name;
	param.manager_computer_name = manager.prt->network_name;
	param.manager_exclude_fs    = manager.exclude_filesys;
	param.blkdevlist 	    = &manager.blkdevlist;
	
	ParseParam(argc, argv, &param);

	g_pVersionStringWithDebug = NULL;	//should use manager object after this...

	iomtr_set_cpu_affinity(param.cpu_affinity);

	// If there were command line parameters, indicate that they were recognized.
	if ( iometer[0] || manager.manager_name[0] )
	{
		cout << "\nCommand line parameter(s):" << endl;

		if ( iometer[0] ) {
			cout << "   Looking for Iometer on \"" << iometer << "\"" << endl;
		}
		if ( manager.manager_name[0] ) {
			cout << "   New manager name is \"" << manager.manager_name << "\"" << endl;
		}
	}
	if ( manager.exclude_filesys[0] )
        {
      		cout << "\nExcluding the following filesystem types:" << endl;
        	cout << "   \"" << manager.exclude_filesys << "\"" << endl;
        }
        else
        {
        	strcpy(manager.exclude_filesys, DEFAULT_EXCLUDE_FILESYS);
        }
	cout << endl;

#if defined(IOMTR_OSFAMILY_UNIX)
 #if defined(IOMTR_OS_LINUX)
	signal(SIGALRM, SIG_IGN);
 #elif defined(IOMTR_OS_SOLARIS)
	sigignore(SIGALRM);
 #else
  #warning ===> WARNING: You have to do some coding here to get the port done!
 #endif 

	// Initialize the lock on UNIX platforms.
	if (pthread_mutex_init(&lock_mt, NULL))
	{
		cout <<"unable to init the lock" << endl;
		exit(1);
	}

	// Block SIGPIPE signal. Needed to ensure that Network worker
	// threads don't exit due to a broken pipe signal.
	sigset_t sigset;
	sigemptyset(&sigset);
	sigaddset(&sigset, SIGPIPE);
	if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0)
	{
		cout << "sigprocmask() call failed." << endl;
		cout << "dynamo could be unstable" << endl;
	}

	//
	// the number of file descriptors a process may create can be a small value like 64.
	//
	struct rlimit rlimitp;
	if (getrlimit(RLIMIT_NOFILE, &rlimitp) < 0)
	{
		cout << "error " << errno << " trying to get rlimit (# file descriptors)" << endl;
	}
	else
	{
		// it succeeded. We leave out atleast 25 file descriptors for non-targets
		// and compare with the hard limit.
		unsigned int targets = MAX_TARGETS + 25;
		if ( rlimitp.rlim_max < targets )
		{
			cout << "Only " << rlimitp.rlim_max << " file descriptors available" << endl;
			rlimitp.rlim_cur = rlimitp.rlim_max;
		}
		else
		{
			// set the soft limit to the required value.
			rlimitp.rlim_cur = targets;
		}
		if (setrlimit(RLIMIT_NOFILE, &rlimitp) < 0)
		{
			cout << "error " << errno << " trying to set rlimit (# file descriptors)" << endl;
		}
	}

	// Check for super-user permissions. If not super-user, we
	// cannot get many of the info from the kernel.
	if (getuid() || geteuid())
	{
		cout << "Dynamo not running as super-user." << endl;
		cout << "       All available disks might not be reported " << endl;
		cout << "       Cannot get TCP statistics from the kernel " << endl;
	}

#ifdef IOMTR_SETTING_OVERRIDE_FS
	// No command line args specifies destructive testing. Check to see if there
	// are any environment variables specifying the same. We need to warn the user.
	if (getenv("IOMTR_SETTING_OVERRIDE_FS") != NULL)
	{
		cout << "       ************ WARNING **************" << endl;
		cout << "       dynamo running in Destructive mode." << endl;
		cout << "         (overriding the not mounted fs)"   << endl;		
		cout << "       ************ WARNING **************" << endl;
	}
#endif // IOMTR_SETTING_OVERRIDE_FS
#endif // IOMTR_OSFAMILY_UNIX
#if defined(IOMTR_OSFAMILY_NETWARE)
	// Initialize the lock on NetWare platforms.
	if (pthread_mutex_init(&lock_mt, NULL))
	{
		cout <<"unable to init the lock" << endl;
		exit(1);
	}
#endif

	// Ensure, that the endian type of the CPU is detectable
	if ( (IsBigEndian() != 0) && (IsBigEndian() != 1) )
	{
		cout << "===> ERROR: Endian type of the CPU couldn't be detected." << endl;
		cout << "     [main() in " << __FILE__ << " line " << __LINE__ << "]" << endl;
		exit(1);
	}

	// Entering infinite loop to allow Dynamo to run multiple tests.  Outer while loop allows
	// Dynamo to be reset from Iometer.  If everything works smoothly, resets should be rare.
	while (TRUE)
	{
		// Initializing worker and logging into Iometer director.
		if ( !manager.Login( iometer ) )
			break;

		// Manager will continue to run until an error, or stopped by Iometer.
		if ( !manager.Run() )
			break;		// Stop running when the manager is done.
	}
	cout << "Ending execution." << endl;
	Sleep( 1000 );

#if defined(IOMTR_OS_LINUX)
	CleanupIoctlInterface(kstatfd);
#if defined(IOMTR_CPU_XSCALE)
	CleanupCCNTInterface(ccntfd);
#endif
#endif
	return(0);
}