/* * This is the meat of the /proc scanner. * It will visit every single LWP in /proc. */ static void collect_lwp_data() { char *pidstr; pid_t pid; id_t lwpid; size_t entsz; long nlwps, nent, i; char *buf, *ptr; char pfile[MAX_PROCFS_PATH]; fds_t *fds; lwp_info_t *lwp; dirent_t *direntp; prheader_t header_buf; psinfo_t psinfo_buf; prusage_t usage_buf; lwpsinfo_t *lwpsinfo_buf; prusage_t *lwpusage_buf; log_msg("->collect_lwp_data(): %d files open\n", fd_count()); for (rewinddir(procdir); (direntp = readdir(procdir)); ) { pidstr = direntp->d_name; if (pidstr[0] == '.') /* skip "." and ".." */ continue; pid = atoi(pidstr); if (pid == 0 || pid == 2 || pid == 3) continue; /* skip sched, pageout and fsflush */ fds = fds_get(pid); /* get ptr to file descriptors */ /* * Here we are going to read information about * current process (pid) from /proc/pid/psinfo file. * If process has more than one lwp, we also should * read /proc/pid/lpsinfo for information about all lwps. */ (void) snprintf(pfile, MAX_PROCFS_PATH, "/proc/%s/psinfo", pidstr); if ((fds->fds_psinfo = fd_open(pfile, O_RDONLY, fds->fds_psinfo)) == NULL) continue; if (pread(fd_getfd(fds->fds_psinfo), &psinfo_buf, sizeof (struct psinfo), 0) != sizeof (struct psinfo)) { fd_close(fds->fds_psinfo); continue; } fd_close(fds->fds_psinfo); nlwps = psinfo_buf.pr_nlwp + psinfo_buf.pr_nzomb; if (nlwps > 1) { (void) snprintf(pfile, MAX_PROCFS_PATH, "/proc/%s/lpsinfo", pidstr); if ((fds->fds_lpsinfo = fd_open(pfile, O_RDONLY, fds->fds_lpsinfo)) == NULL) continue; entsz = sizeof (struct prheader); if (pread(fd_getfd(fds->fds_lpsinfo), &header_buf, entsz, 0) != entsz) { fd_close(fds->fds_lpsinfo); continue; } nent = header_buf.pr_nent; entsz = header_buf.pr_entsize * nent; ptr = buf = Malloc(entsz); if (pread(fd_getfd(fds->fds_lpsinfo), buf, entsz, sizeof (struct prheader)) != entsz) { fd_close(fds->fds_lpsinfo); Free(buf); continue; } fd_close(fds->fds_lpsinfo); for (i = 0; i < nent; i++, ptr += header_buf.pr_entsize) { /*LINTED ALIGNMENT*/ lwpsinfo_buf = (lwpsinfo_t *)ptr; lwpid = lwpsinfo_buf->pr_lwpid; if ((lwp = lwpid_get(pid, lwpid)) == NULL) { lwp = list_add_lwp(&lwps, pid, lwpid); } if (i == 0) lwp->rlwpid = lwpid; (void) memcpy(lwp->li_psinfo, &psinfo_buf, sizeof (psinfo_t) - sizeof (lwpsinfo_t)); lwp->li_alive = B_TRUE; (void) memcpy(lwp->li_lwpsinfo, lwpsinfo_buf, sizeof (lwpsinfo_t)); } Free(buf); } else { lwpid = psinfo_buf.pr_lwp.pr_lwpid; if ((lwp = lwpid_get(pid, lwpid)) == NULL) { lwp = list_add_lwp(&lwps, pid, lwpid); } lwp->rlwpid = lwpid; (void) memcpy(lwp->li_psinfo, &psinfo_buf, sizeof (psinfo_t) - sizeof (lwpsinfo_t)); lwp->li_alive = B_TRUE; (void) memcpy(lwp->li_lwpsinfo, &psinfo_buf.pr_lwp, sizeof (lwpsinfo_t)); lwp->li_lwpsinfo->pr_pctcpu = lwp->li_psinfo->pr_pctcpu; } /* * At this part of scandir we read additional information * about processes from /proc/pid/usage file. * Again, if process has more than one lwp, then we * will get information about all its lwps from * /proc/pid/lusage file. */ if (nlwps > 1) { (void) snprintf(pfile, MAX_PROCFS_PATH, "/proc/%s/lusage", pidstr); if ((fds->fds_lusage = fd_open(pfile, O_RDONLY, fds->fds_lusage)) == NULL) continue; entsz = sizeof (struct prheader); if (pread(fd_getfd(fds->fds_lusage), &header_buf, entsz, 0) != entsz) { fd_close(fds->fds_lusage); continue; } nent = header_buf.pr_nent; entsz = header_buf.pr_entsize * nent; buf = Malloc(entsz); if (pread(fd_getfd(fds->fds_lusage), buf, entsz, sizeof (struct prheader)) != entsz) { fd_close(fds->fds_lusage); Free(buf); continue; } fd_close(fds->fds_lusage); for (i = 1, ptr = buf + header_buf.pr_entsize; i < nent; i++, ptr += header_buf.pr_entsize) { /*LINTED ALIGNMENT*/ lwpusage_buf = (prusage_t *)ptr; lwpid = lwpusage_buf->pr_lwpid; if ((lwp = lwpid_get(pid, lwpid)) == NULL) continue; lwp_update(lwp, lwpusage_buf); } Free(buf); } else { (void) snprintf(pfile, MAX_PROCFS_PATH, "/proc/%s/usage", pidstr); if ((fds->fds_usage = fd_open(pfile, O_RDONLY, fds->fds_usage)) == NULL) continue; entsz = sizeof (prusage_t); if (pread(fd_getfd(fds->fds_usage), &usage_buf, entsz, 0) != entsz) { fd_close(fds->fds_usage); continue; } fd_close(fds->fds_usage); lwpid = psinfo_buf.pr_lwp.pr_lwpid; if ((lwp = lwpid_get(pid, lwpid)) == NULL) continue; lwp_update(lwp, &usage_buf); } } list_refresh(&lwps); fd_update(); log_msg("<-collect_lwp_data(): %d files open\n", fd_count()); }
static void prstat_scandir(DIR *procdir) { char *pidstr; pid_t pid; id_t lwpid; size_t entsz; long nlwps, nent, i; char *buf, *ptr; fds_t *fds; lwp_info_t *lwp; dirent_t *direntp; prheader_t header; psinfo_t psinfo; prusage_t usage; lwpsinfo_t *lwpsinfo; prusage_t *lwpusage; total_procs = 0; total_lwps = 0; total_cpu = 0; total_mem = 0; convert_zone(&zone_tbl); for (rewinddir(procdir); (direntp = readdir(procdir)); ) { pidstr = direntp->d_name; if (pidstr[0] == '.') /* skip "." and ".." */ continue; pid = atoi(pidstr); if (pid == 0 || pid == 2 || pid == 3) continue; /* skip sched, pageout and fsflush */ if (has_element(&pid_tbl, pid) == 0) continue; /* check if we really want this pid */ fds = fds_get(pid); /* get ptr to file descriptors */ if (read_procfile(&fds->fds_psinfo, pidstr, "psinfo", &psinfo, sizeof (psinfo_t)) != 0) continue; if (!has_uid(&ruid_tbl, psinfo.pr_uid) || !has_uid(&euid_tbl, psinfo.pr_euid) || !has_element(&prj_tbl, psinfo.pr_projid) || !has_element(&tsk_tbl, psinfo.pr_taskid) || !has_zone(&zone_tbl, psinfo.pr_zoneid)) { fd_close(fds->fds_psinfo); continue; } nlwps = psinfo.pr_nlwp + psinfo.pr_nzomb; if (nlwps > 1 && (opts.o_outpmode & (OPT_LWPS | OPT_PSETS))) { int rep_lwp = 0; if (read_procfile(&fds->fds_lpsinfo, pidstr, "lpsinfo", &header, sizeof (prheader_t)) != 0) { fd_close(fds->fds_psinfo); continue; } nent = header.pr_nent; entsz = header.pr_entsize * nent; ptr = buf = Malloc(entsz); if (pread(fd_getfd(fds->fds_lpsinfo), buf, entsz, sizeof (struct prheader)) != entsz) { fd_close(fds->fds_lpsinfo); fd_close(fds->fds_psinfo); free(buf); continue; } nlwps = 0; for (i = 0; i < nent; i++, ptr += header.pr_entsize) { /*LINTED ALIGNMENT*/ lwpsinfo = (lwpsinfo_t *)ptr; if (!has_element(&cpu_tbl, lwpsinfo->pr_onpro) || !has_element(&set_tbl, lwpsinfo->pr_bindpset)) continue; nlwps++; if ((opts.o_outpmode & (OPT_PSETS | OPT_LWPS)) == OPT_PSETS) { /* * If one of process's LWPs is bound * to a given processor set, report the * whole process. We may be doing this * a few times but we'll get an accurate * lwp count in return. */ add_proc(&psinfo); } else { if (rep_lwp == 0) { rep_lwp = 1; add_lwp(&psinfo, lwpsinfo, LWP_REPRESENT); } else { add_lwp(&psinfo, lwpsinfo, 0); } } } free(buf); if (nlwps == 0) { fd_close(fds->fds_lpsinfo); fd_close(fds->fds_psinfo); continue; } } else { if (!has_element(&cpu_tbl, psinfo.pr_lwp.pr_onpro) || !has_element(&set_tbl, psinfo.pr_lwp.pr_bindpset)) { fd_close(fds->fds_psinfo); continue; } add_proc(&psinfo); } if (!(opts.o_outpmode & OPT_MSACCT)) { total_procs++; total_lwps += nlwps; continue; } /* * Get more information about processes from /proc/pid/usage. * If process has more than one lwp, then we may have to * also look at the /proc/pid/lusage file. */ if ((opts.o_outpmode & OPT_LWPS) && (nlwps > 1)) { if (read_procfile(&fds->fds_lusage, pidstr, "lusage", &header, sizeof (prheader_t)) != 0) { fd_close(fds->fds_lpsinfo); fd_close(fds->fds_psinfo); continue; } nent = header.pr_nent; entsz = header.pr_entsize * nent; buf = Malloc(entsz); if (pread(fd_getfd(fds->fds_lusage), buf, entsz, sizeof (struct prheader)) != entsz) { fd_close(fds->fds_lusage); fd_close(fds->fds_lpsinfo); fd_close(fds->fds_psinfo); free(buf); continue; } for (i = 1, ptr = buf + header.pr_entsize; i < nent; i++, ptr += header.pr_entsize) { /*LINTED ALIGNMENT*/ lwpusage = (prusage_t *)ptr; lwpid = lwpusage->pr_lwpid; /* * New LWPs created after we read lpsinfo * will be ignored. Don't want to do * everything all over again. */ if ((lwp = lwpid_get(pid, lwpid)) == NULL) continue; lwp_update(lwp, pid, lwpid, lwpusage); } free(buf); } else { if (read_procfile(&fds->fds_usage, pidstr, "usage", &usage, sizeof (prusage_t)) != 0) { fd_close(fds->fds_lpsinfo); fd_close(fds->fds_psinfo); continue; } lwpid = psinfo.pr_lwp.pr_lwpid; if ((lwp = lwpid_get(pid, lwpid)) == NULL) continue; lwp_update(lwp, pid, lwpid, &usage); } total_procs++; total_lwps += nlwps; } fd_update(); }
int main(int argc,char *argv[]) { fd_count=0; lgfile=fopen("logfile.txt","w"); /* Locking File Config */ file_lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ file_lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ file_lock.l_start = 0; /* Offset from l_whence */ file_lock.l_len = 0; /* length, 0 = to EOF */ file_lock.l_pid = getpid(); /* our PID */ /*Locking File Config */ strcpy(home_folder,argv[2]); strcpy(address,argv[3]); strcpy(dest_folder,argv[4]); int fd=fd_update(home_folder,-1); /* Initalizing linked-list head */ pid_list.starting=NULL; pid_list.last=NULL; /*Initializing linked list head */ /* Setting signal. */ signal(SIGINT,sigint_handler); signal(SIGALRM,timeout); /* Setting signal. */ struct reading_info input; input.fd=fd; alarm(atoi(argv[1])); event_occurred_count=0; subprocess_count=0; /*Creating thread for inotify. */ int retvalue; if ((retvalue=pthread_create(&inotify_thread,NULL,&wait_for_events,&input))) { printf("Thread creation failure. Code: %d\n",retvalue); } /*Initializing thread-lock variable*/ if ((pthread_mutex_init(&inotify_event_lock,NULL))) { printf("Lock initialization error. Fatal.\n:"); exit(EXIT_FAILURE); } /*Initializing thread-lock variable*/ int status1,i; char com[80]; if (test_if_dir_exists(home_folder)!=0) { printf("Making dir...\n"); sprintf(com,"mkdir %s",home_folder); exec_pipe(com,0); waitpid(-1,&status1,0); } /* An initial rsync to sync the two folders */ sprintf(com,"rsync -azsre ssh --delete \"%s/\" \"%s:%s\"",home_folder,address,dest_folder); int sleeptime_initial=5; char *temp=(char *)malloc(sizeof(char)*(strlen(com)+3)); strcpy(temp,com); int exit_status=exec_pipe(com,0); waitpid(exit_status,&status1,0); while (WEXITSTATUS(status1)!=0) { strcpy(com,temp); exit_status=exec_pipe(com,sleeptime_initial); waitpid(exit_status,&status1,0); if (sleeptime_initial<1280) {sleeptime_initial*=2;} } /* An initial rsync to sync the two folders */ while(1) { if (event_occurred_count!=0 && subprocess_count<MAX_EVENT_STACK_SIZE) { pthread_mutex_lock(&inotify_event_lock); int i=0; while (i<event_occurred_count) { read_event_shell(event_stack[i],fd); event_stack[i]=NULL; i+=1; } event_occurred_count=0; pthread_mutex_unlock(&inotify_event_lock); } for (i=0;i<2;i++) { poll_pids(); sleep(1); } } destroy_all(); fclose(lgfile); return 0; }