static int rtasd(void *unused)
{
unsigned int err_type;
int cpu = 0;
int event_scan = rtas_token("event-scan");
cpumask_t all = CPU_MASK_ALL;
int rc;
daemonize("rtasd");
if (event_scan == RTAS_UNKNOWN_SERVICE || get_eventscan_parms() == -1)
goto error;
rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
if (!rtas_log_buf) {
printk(KERN_ERR "rtasd: no memory\n");
goto error;
}
/* We can use rtas_log_buf now */
no_more_logging = 0;
printk(KERN_ERR "RTAS daemon started\n");
DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
/* See if we have any error stored in NVRAM */
memset(logdata, 0, rtas_error_log_max);
rc = nvram_read_error_log(logdata, rtas_error_log_max, &err_type);
if (!rc) {
if (err_type != ERR_FLAG_ALREADY_LOGGED) {
pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
}
}
/* First pass. */
lock_cpu_hotplug();
for_each_online_cpu(cpu) {
DEBUG("scheduling on %d\n", cpu);
set_cpus_allowed(current, cpumask_of_cpu(cpu));
DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id());
do_event_scan(event_scan);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
}
unlock_cpu_hotplug();
if (surveillance_timeout != -1) {
DEBUG("enabling surveillance\n");
enable_surveillance(surveillance_timeout);
DEBUG("surveillance enabled\n");
}
lock_cpu_hotplug();
cpu = first_cpu_const(mk_cpumask_const(cpu_online_map));
for (;;) {
set_cpus_allowed(current, cpumask_of_cpu(cpu));
do_event_scan(event_scan);
set_cpus_allowed(current, all);
/* Drop hotplug lock, and sleep for a bit (at least
* one second since some machines have problems if we
* call event-scan too quickly). */
unlock_cpu_hotplug();
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout((HZ*60/rtas_event_scan_rate) / 2);
lock_cpu_hotplug();
cpu = next_cpu_const(cpu, mk_cpumask_const(cpu_online_map));
if (cpu == NR_CPUS)
cpu = first_cpu_const(mk_cpumask_const(cpu_online_map));
}
error:
/* Should delete proc entries */
return -EINVAL;
}
/*
* This is the NFS server kernel thread
*/
static void
nfsd(struct svc_rqst *rqstp)
{
struct svc_serv *serv = rqstp->rq_server;
struct fs_struct *fsp;
int err;
struct nfsd_list me;
sigset_t shutdown_mask, allowed_mask;
/* Lock module and set up kernel thread */
lock_kernel();
daemonize("nfsd");
current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
/* After daemonize() this kernel thread shares current->fs
* with the init process. We need to create files with a
* umask of 0 instead of init's umask. */
fsp = copy_fs_struct(current->fs);
if (!fsp) {
printk("Unable to start nfsd thread: out of memory\n");
goto out;
}
exit_fs(current);
current->fs = fsp;
current->fs->umask = 0;
siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS);
siginitsetinv(&allowed_mask, ALLOWED_SIGS);
nfsdstats.th_cnt++;
lockd_up(); /* start lockd */
me.task = current;
list_add(&me.list, &nfsd_list);
unlock_kernel();
/*
* We want less throttling in balance_dirty_pages() so that nfs to
* localhost doesn't cause nfsd to lock up due to all the client's
* dirty pages.
*/
current->flags |= PF_LESS_THROTTLE;
/*
* The main request loop
*/
for (;;) {
/* Block all but the shutdown signals */
sigprocmask(SIG_SETMASK, &shutdown_mask, NULL);
/*
* Find a socket with data available and call its
* recvfrom routine.
*/
while ((err = svc_recv(serv, rqstp,
60*60*HZ)) == -EAGAIN)
;
if (err < 0)
break;
update_thread_usage(atomic_read(&nfsd_busy));
atomic_inc(&nfsd_busy);
/* Lock the export hash tables for reading. */
exp_readlock();
/* Process request with signals blocked. */
sigprocmask(SIG_SETMASK, &allowed_mask, NULL);
svc_process(serv, rqstp);
/* Unlock export hash tables */
exp_readunlock();
update_thread_usage(atomic_read(&nfsd_busy));
atomic_dec(&nfsd_busy);
}
if (err != -EINTR) {
printk(KERN_WARNING "nfsd: terminating on error %d\n", -err);
} else {
unsigned int signo;
for (signo = 1; signo <= _NSIG; signo++)
if (sigismember(¤t->pending.signal, signo) &&
!sigismember(¤t->blocked, signo))
break;
err = signo;
}
lock_kernel();
/* Release lockd */
lockd_down();
/* Check if this is last thread */
if (serv->sv_nrthreads==1) {
//.........这里部分代码省略.........
//-----main function------------------------------------------------------------------------------------------------------------
int main( int argc, char *argv[] )
{
if (argc == 2) //shortcut to daemonize or not
{ if (strcmp(argv[1],"1") == 0) {daemonize();} }
struct clientParams controlClient[MAXTHREADS]; //array of struct which control the threads
pthread_t clientThreads[MAXTHREADS]; //array of threads
int clientSocket[MAXTHREADS];
int yes = 1; //used in setsockopt function
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t sin_size;
int i=0;
FILE *fUser; //the users present in the file are copied to the array
if(fUser=fopen("user.txt","r"))
{
while(fscanf(fUser,"%s %s",userInfo[numUsers].user, userInfo[numUsers].pass)==2)
{ numUsers++;}
fclose(fUser);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); }
if (setsockopt(sockfd,SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int)) == -1) { perror("setsockopt"); exit(1); }
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) { perror("bind"); exit(1); }
if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); }
int reset = 0; //checks if all the threads are used
struct timeval timeout; //used for creating the timeout
timeout.tv_usec = 0; //needed as parameter, else timeout doesnt work since it takes any random value
char recvCheck[DATASIZE]; //recieve the message during timeout, control for setsockopt
for(;;)
{
printf("id: %d Waiting for a connection...\n", getpid()); //since we use 2 threads for each client, other connections with 1 socket are denied
if ((clientSocket[i] = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept");} //1st connection
timeout.tv_sec = 1; //timeout is set to 1 sec
if(setsockopt(clientSocket[i], SOL_SOCKET, SO_RCVTIMEO, (struct timeout *)&timeout, sizeof(timeout)) < 0) {perror("setsockopt failed");}
recv(clientSocket[i], recvCheck, DATASIZE, 0); //recv is active for 1 sec
timeout.tv_sec = 0; //timeout is disabled
if(setsockopt(clientSocket[i], SOL_SOCKET, SO_RCVTIMEO, (struct timeout *)&timeout, sizeof(timeout)) < 0) {perror("setsockopt failed");}
if (strcmp(recvCheck, "thing") == 0) //if the right string was recieved during 1 sec, accept the connection from next socket, run the program
{
printf("I got the right thing.\n");
if ((clientSocket[i+1] = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept");}
printf("Accepted Connections\n");
if (reset) //if reset=1, join present i and i+1 threads before creating new threads
{
pthread_tryjoin_np(clientThreads[i], NULL);
pthread_tryjoin_np(clientThreads[i+1], NULL);
}
printf("Creating thread %d\n", i); //Thread 1: listener function
controlClient[i].threadId=i;
controlClient[i].clientSocket=clientSocket[i];
controlClient[i].recvError = 0;
pthread_create(&clientThreads[i], NULL, &serverListener, &controlClient[i]);
printf("Creating thread %d\n", i+1); //Thread 2: sender function
controlClient[i+1].threadId=(i+1);
controlClient[i+1].clientSocket=clientSocket[i+1];
controlClient[i+1].recvError = 0;
pthread_create(&clientThreads[i+1], NULL, &serverSender, &controlClient[i+1]);
i+=2; //increased by 2 since threads work in pairs
if (i == MAXTHREADS) //if all threads are used, start over from 0
{ i = 0; reset = 1; }
strcpy(recvCheck, " "); //reset the recvCheck to check further incoming connections
}
else //if nothing or something wrong with one socket was recieved, close the current socket and restart the loop
{
printf("I didnt get the right thing. Closing socket.\n");
close(clientSocket[i]);
}
}
return 0;
}
int execute_arguments(char *program_name, struct hash_map_t *arguments) {
/* allocates space for the possible argument
to be executed from the arguments map */
void *value;
/* allocates the value to be used to verify the
exitence of error from the function */
ERROR_CODE return_value;
/* sets space for the flag that will control if
the service should be run or not, this is used
for certain situations (mostyle test) where the
service is not meant to be run */
char run_service = TRUE;
/* tries to retrieve the help argument from the arguments
map in case the value exists prints the help value and then
exits the current system */
get_value_string_hash_map(arguments, (unsigned char *) "help", &value);
if(value != NULL) {
return help();
}
/* tries to retrieve the version argument from the arguments
map in case the value exists prints the version value and then
exits the current system */
get_value_string_hash_map(arguments, (unsigned char *) "version", &value);
if(value != NULL) {
return version();
}
/* retrieves the test argument value from the arguments map
and in case it's set starts the test process runing a series
of test functions in sequence */
get_value_string_hash_map(arguments, (unsigned char *) "test", &value);
if(value != NULL) {
return test();
}
/* retrieves the speed argument value from the arguments map
and in case it's set starts the speed measuring and disables
the runnig of the service */
get_value_string_hash_map(arguments, (unsigned char *) "speed", &value);
if(value != NULL) {
return speed();
}
/* tries to retrieve the daemon argument from the
arguments map in case the value is set daemonizes
the current process so that it remains in background
and returns to the caller process immediately, otherwise
prints the viriatum information into the standard
output "file", the label should be standard */
get_value_string_hash_map(arguments, (unsigned char *) "daemon", &value);
if(value != NULL) {
daemonize();
}
else {
print_information();
}
/* tries to retrieve the local argument from the arguments
map in case the value exists localizes the current service
so that any file read is read from the current directory */
get_value_string_hash_map(arguments, (unsigned char *) "local", &value);
if(value != NULL) {
localize();
}
/* in cas the flag that control if the service must be run is
unset the control flow must be returned immediately (avoids
running service) */
if(run_service == FALSE) {
RAISE_NO_ERROR;
}
/* runs the service, with the given arguments, this call
should block the program control flow until an event
stop the running of the main loop */
return_value = run_service_s(program_name, arguments);
/* tests the error code for error in case it exists
prints a message indicating the problem that occurred */
if(IS_ERROR_CODE(return_value)) {
V_ERROR_F("Problem running service (%s)\n", (char *) GET_ERROR());
RAISE_AGAIN(return_value);
}
/* returns the normal result value as no problems has
occured during the execution of the command */
RAISE_NO_ERROR;
}
请发表评论