66#include  <string.h> 
77#include  <dirent.h> 
88#include  <regex.h> 
9+ #include  <time.h> 
910#include  <sys/fcntl.h> 
1011#include  <sys/socket.h> 
1112#include  <sys/un.h> 
@@ -563,6 +564,88 @@ cmd_update(int argc, char *argv[])
563564			  /* send_fd */  -1 );
564565}
565566
567+ #ifdef  STRESS_TEST 
568+ 
569+ struct  test_data  {
570+ 	int  option_period ;
571+ 	int  stat_cycle_num ;
572+ } test_info  =  { .option_period  =  0 , .stat_cycle_num  =  0  };
573+ 
574+ static  int 
575+ server_wait (int  pid , int  period )
576+ {
577+ 	struct  timespec  req , rem ;
578+ 	int  i ;
579+ 	req .tv_sec  =  0 ;
580+ 	req .tv_nsec  =  1000 * 1000 ;
581+ 	for  (i = 0 ; i < period ; i ++ ) {
582+ 		nanosleep (& req , & rem );
583+ 		if  (kill (pid , 0 ) !=  0 ) {
584+ 			fprintf (stderr , "Process %d terminated.\n" , pid );
585+ 			return  -1 ;
586+ 		}
587+ 	}
588+ 	return  0 ;
589+ }
590+ 
591+ static  int 
592+ server_stress_test (int  fd , int  argc , char  * argv [])
593+ {
594+ 	int  pid ;
595+ 	int  delay ;
596+ 	test_info .stat_cycle_num  =  0 ;
597+ 	srand (time (NULL ));
598+ 
599+ 	if  (sscanf (argv [1 ], "%d" , & pid ) !=  1 ) {
600+ 		kperr ("Can't parse pid from %s\n" , argv [1 ]);
601+ 		return  -1 ;
602+ 	}
603+ 
604+ 	while  (1 ) {
605+ 		while  (patch_user (storage_dir , pid , 0 , fd ) <  0 )
606+ 			if  (server_wait (pid , 1 ) <  0 )
607+ 				return  0 ;
608+ 		if  (fd  >  0 )
609+ 			close (fd );
610+ 		fd  =  -1 ;
611+ 		if  (test_info .option_period  ==  0 )
612+ 			return  0 ;
613+ 		delay  =  rand () % test_info .option_period ;
614+ 		if  (server_wait (pid , delay ) <  0 )
615+ 			return  0 ;
616+ 
617+ 		while  (processes_unpatch (pid , 0 , 0 ) <  0 )
618+ 			if  (server_wait (pid , 1 ) <  0 )
619+ 				return  0 ;
620+ 		test_info .stat_cycle_num ++ ;
621+ 
622+ 		delay  =  rand () % test_info .option_period ;
623+ 		if  (server_wait (pid , delay ) <  0 )
624+ 			return  0 ;
625+ 	}
626+ 
627+ 	return  0 ;
628+ }
629+ 
630+ static  int  cmd_stress_test (int  fd , int  argc , char  * argv [])
631+ {
632+ 	int  child  =  fork ();
633+ 	if  (child  ==  0 ) {
634+ 		int  rv  =  server_stress_test (fd , argc , argv );
635+ 		exit (rv );
636+ 	}
637+ 	close (fd );
638+ 	return  0 ;
639+ }
640+ 
641+ static  int  usage_stresstest ()
642+ {
643+ 	fprintf (stderr , "usage: libcare-stresstest PERIOD(ms, 0 - only patch) <UNIX socket> [STORAGE ROOT]\n" );
644+ 	return  -1 ;
645+ }
646+ 
647+ #endif 
648+ 
566649static  int 
567650server_execute_cmd (int  fd , int  argc , char  * argv [])
568651{
@@ -572,8 +655,13 @@ server_execute_cmd(int fd, int argc, char *argv[])
572655
573656	if  (!strcmp (cmd , "execve" ))
574657		return  cmd_execve_startup (fd , argc , argv , 1 );
575- 	if  (!strcmp (cmd , "startup" ))
658+ 	if  (!strcmp (cmd , "startup" )) {
659+ #ifdef  STRESS_TEST 
660+ 		return  cmd_stress_test (fd , argc , argv );
661+ #else 
576662		return  cmd_execve_startup (fd , argc , argv , 0 );
663+ #endif 
664+ 	}
577665	if  (!strcmp (cmd , "update" ))
578666		return  cmd_update (argc , argv );
579667	if  (!strcmp (cmd , "storage" ))
@@ -739,6 +827,12 @@ cmd_server(int argc, char *argv[])
739827		return  -1 ;
740828	}
741829
830+ #ifdef  STRESS_TEST 
831+ 	if  (sscanf (argv [0 ], "%d" , & test_info .option_period ) !=  1 ) {
832+ 		kplogerror ("Can't parse period from %s\n" , argv [0 ]);
833+ 	}
834+ #endif 
835+ 
742836	sfd  =  server_bind_socket (argv [1 ]);
743837	if  (sfd  <  0 )
744838		return  sfd ;
@@ -824,6 +918,9 @@ static int usage(const char *err)
824918{
825919	if  (err )
826920		fprintf (stderr , "err: %s\n" , err );
921+ #ifdef  STRESS_TEST 
922+ 	return  usage_stresstest ();
923+ #endif 
827924	fprintf (stderr , "usage: libcare-ctl [options] <cmd> [args]\n" );
828925	fprintf (stderr , "\nOptions:\n" );
829926	fprintf (stderr , "  -v          - verbose mode\n" );
@@ -872,11 +969,18 @@ int main(int argc, char *argv[])
872969	argc  -=  optind ;
873970	argv  +=  optind ;
874971
972+ #ifdef  STRESS_TEST 
973+ 	if  (argc  <  3 )
974+ 		return  usage ("not enough arguments." );
975+ 	signal (SIGCHLD , SIG_IGN );
976+ 	return  cmd_server (argc , argv );
977+ #else 
875978	if  (argc  <  1 )
876979		return  usage ("not enough arguments." );
877980
878981	if  (!strcmp (argv [0 ], "server" ))
879982		return  cmd_server (argc , argv );
880983	else 
881984		return  execute_cmd (argc , argv );
985+ #endif 
882986}
0 commit comments