예제 #1
0
파일: rdimpl.c 프로젝트: andreiw/polaris
/*
 * 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());
}
예제 #2
0
파일: prstat.c 프로젝트: andreiw/polaris
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();
}
예제 #3
0
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;
}