Procps in Solaris


 
Thread Tools Search this Thread
Top Forums Programming Procps in Solaris
# 1  
Old 12-06-2012
Procps in Solaris

Hello All

I am trying to write my own "ps" function by reading the /proc folder and going through each PID folder and getting only a few specific information. On Linux this is easy as the information is stored as text; but on Solaris it seems to be binary.

Does anyone have experience looking through procps code to see how the actual PS command gets process information in Solaris? I tried emailing Albert Cahalan who wrote it but I am too obsecure to get a hold of him.

Please note, executing a system command with PS in my project is out of the question, I must manually get the proc information without using other system commands.

Thanks for your help
# 2  
Old 12-06-2012
This may or may not correspond with your system, but it may provide food for thought: psinfo_t used by print_proc() in ps.c

Regards,
Alister
# 3  
Old 12-06-2012
There are headers in Solaris , procfs.h.

These define the structs used to read the /proc files. And you are right, a lot of the data is binary. One or two of the "files" in /proc/<pid> are directories. /proc/<pid>/path
is very informative with just
Code:
ls-l /proc/self/path

as an example usage.

Example code (modified from an example by R Teer)

Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <time.h>
// #define NEED_SNPRINTF
#ifdef NEED_SNPRINTF
#include <sys/procfs.h>
#else
#include <sys/old_procfs.h>
#endif
#include <limits.h>
// #include "ssp.h"
 extern
 void  get_mem(pid_t pid);
 int getprusage (pid_t pid, prusage_t *pr_usage);
 void print_rusage (pid_t pid, prusage_t *buf);

char dest[64]={0x0};


int main (int argc, char **argv)
{
	pid_t pid;
	prusage_t buf;
	int i;

	if (argc == 1)
	{
		if (getprusage (-1, &buf) == -1)
			{
				perror("getprusage failed");
				exit(1);
			}

		  print_rusage (getpid (), &buf);
		  get_mem(getpid() );
	}
	else
	{
		for (i = 1; i < argc; i++) {
			pid = atoi (argv [i]);
			if (getprusage (pid, &buf) == -1)
			{
				 perror("getprusage failed");
				 exit(1);
		  }
			else
		  {
				print_rusage (pid, &buf);
				get_mem(pid);
			}
		}
	}

	return 0;
}

 int getprusage (pid_t pid, prusage_t *pr_usage)
{
	int fd;
	char name [PATH_MAX];
  
	if (pid == -1)
		snprintf (name, PATH_MAX, "/proc/%ld", (long) getpid ());
	else
		snprintf (name, PATH_MAX, "/proc/%ld", (long) pid);

	if ((fd = open (name, O_RDONLY)) == -1)
		return (-1);
   
	if (ioctl (fd, PIOCUSAGE, pr_usage) == -1) {
		close (fd);
		return (-1);
	}
	else {
		close (fd);
		return (0);
	}
}

void print_rusage(pid_t pid, prusage_t *buf)
{
  printf ("Resource usage for PID %ld:\n", (long) pid);
 printf ("  LWP ID: %ld\n", (long) buf -> pr_lwpid);
 printf ("  Number of LWPs: %d\n", (int) buf -> pr_count);
 printf ("  Timestamp: %ld.%ld\n", buf -> pr_tstamp.tv_sec,
 	              buf -> pr_tstamp.tv_nsec);
 printf ("  Creation time: %ld.%ld\n", buf -> pr_create.tv_sec,
 	             buf -> pr_create.tv_nsec);
 printf ("  Termination time: %ld.%ld\n", buf -> pr_term.tv_sec,
 	              buf -> pr_term.tv_nsec);
  printf ("  Real (elapsed) time: %ld.%ld\n", buf -> pr_rtime.tv_sec,
	              buf -> pr_rtime.tv_nsec);
  printf ("  User CPU time: %ld.%ld\n", buf -> pr_utime.tv_sec,
  	     buf -> pr_utime.tv_nsec);
  printf ("  System CPU time: %ld.%ld\n", buf -> pr_stime.tv_sec,
  	     buf -> pr_stime.tv_nsec);
  printf ("  System trap CPU time: %ld.%ld\n", buf -> pr_ttime.tv_sec,
  	buf -> pr_ttime.tv_nsec);
  printf ("  Text page fault CPU time: %ld.%ld\n", buf -> pr_tftime.tv_sec,
  	buf -> pr_tftime.tv_nsec);
  printf ("  Data page fault CPU time: %ld.%ld\n", buf -> pr_dftime.tv_sec,
  	buf -> pr_dftime.tv_nsec);
  printf ("  Kernel page fault CPU time: %ld.%ld\n", buf -> pr_kftime.tv_sec,
  	buf -> pr_kftime.tv_nsec);
  printf ("  User lock wait time: %ld.%ld\n", buf -> pr_ltime.tv_sec,
  	buf -> pr_ltime.tv_nsec);
  printf ("  Other sleep time: %ld.%ld\n", buf -> pr_slptime.tv_sec,
  	buf -> pr_slptime.tv_nsec);
  printf ("  CPU latency time: %ld.%ld\n", buf -> pr_wtime.tv_sec,
  	buf -> pr_wtime.tv_nsec);
  printf ("  Stopped time: %ld.%ld\n", buf -> pr_stoptime.tv_sec,
  	buf -> pr_stoptime.tv_nsec);
  printf ("  Minor faults: %ld\n", buf -> pr_minf);
  printf ("  Major faults: %ld\n", buf -> pr_majf);
  printf ("  Number of swaps: %ld\n", buf -> pr_nswap);
  printf ("  Input blocks: %ld\n", buf -> pr_inblk);
  printf ("  Output blocks: %ld\n", buf -> pr_oublk);
  printf ("  Messages sent: %ld\n", buf -> pr_msnd);
  printf ("  Messages received: %ld\n", buf -> pr_mrcv);
  printf ("  Signals received: %ld\n", buf -> pr_sigs);
  printf ("  Voluntary context switches: %ld\n", buf -> pr_vctx);
  printf ("  Involuntary context switches: %ld\n", buf -> pr_ictx);
  printf ("  System calls: %ld\n", buf -> pr_sysc);
	printf ("  Characters read/written: %ld\n", buf -> pr_ioch);
	return;
}

/*
*  /proc/pid/status
*/

This User Gave Thanks to jim mcnamara For This Post:
# 4  
Old 12-06-2012
There are headers in Solaris , procfs.h.

These define the structs used to read the /proc files. And you are right, a lot of the data is binary. One or two of the "files" in /proc/<pid> are directories. /proc/<pid>/path
is very informative with just
Code:
ls-l /proc/self/path

as an example usage.

Example code (modified from an example by R Teer)

Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <time.h>
// #define NEED_SNPRINTF
#ifdef NEED_SNPRINTF
#include <sys/procfs.h>
#else
#include <sys/old_procfs.h>
#endif
#include <limits.h>
// #include "ssp.h"
 extern
 void  get_mem(pid_t pid);
 int getprusage (pid_t pid, prusage_t *pr_usage);
 void print_rusage (pid_t pid, prusage_t *buf);

char dest[64]={0x0};


int main (int argc, char **argv)
{
	pid_t pid;
	prusage_t buf;
	int i;

	if (argc == 1)
	{
		if (getprusage (-1, &buf) == -1)
			{
				perror("getprusage failed");
				exit(1);
			}

		  print_rusage (getpid (), &buf);
		  get_mem(getpid() );
	}
	else
	{
		for (i = 1; i < argc; i++) {
			pid = atoi (argv [i]);
			if (getprusage (pid, &buf) == -1)
			{
				 perror("getprusage failed");
				 exit(1);
		  }
			else
		  {
				print_rusage (pid, &buf);
				get_mem(pid);
			}
		}
	}

	return 0;
}

 int getprusage (pid_t pid, prusage_t *pr_usage)
{
	int fd;
	char name [PATH_MAX];
  
	if (pid == -1)
		snprintf (name, PATH_MAX, "/proc/%ld", (long) getpid ());
	else
		snprintf (name, PATH_MAX, "/proc/%ld", (long) pid);

	if ((fd = open (name, O_RDONLY)) == -1)
		return (-1);
   
	if (ioctl (fd, PIOCUSAGE, pr_usage) == -1) {
		close (fd);
		return (-1);
	}
	else {
		close (fd);
		return (0);
	}
}

void print_rusage(pid_t pid, prusage_t *buf)
{
  printf ("Resource usage for PID %ld:\n", (long) pid);
 printf ("  LWP ID: %ld\n", (long) buf -> pr_lwpid);
 printf ("  Number of LWPs: %d\n", (int) buf -> pr_count);
 printf ("  Timestamp: %ld.%ld\n", buf -> pr_tstamp.tv_sec,
 	              buf -> pr_tstamp.tv_nsec);
 printf ("  Creation time: %ld.%ld\n", buf -> pr_create.tv_sec,
 	             buf -> pr_create.tv_nsec);
 printf ("  Termination time: %ld.%ld\n", buf -> pr_term.tv_sec,
 	              buf -> pr_term.tv_nsec);
  printf ("  Real (elapsed) time: %ld.%ld\n", buf -> pr_rtime.tv_sec,
	              buf -> pr_rtime.tv_nsec);
  printf ("  User CPU time: %ld.%ld\n", buf -> pr_utime.tv_sec,
  	     buf -> pr_utime.tv_nsec);
  printf ("  System CPU time: %ld.%ld\n", buf -> pr_stime.tv_sec,
  	     buf -> pr_stime.tv_nsec);
  printf ("  System trap CPU time: %ld.%ld\n", buf -> pr_ttime.tv_sec,
  	buf -> pr_ttime.tv_nsec);
  printf ("  Text page fault CPU time: %ld.%ld\n", buf -> pr_tftime.tv_sec,
  	buf -> pr_tftime.tv_nsec);
  printf ("  Data page fault CPU time: %ld.%ld\n", buf -> pr_dftime.tv_sec,
  	buf -> pr_dftime.tv_nsec);
  printf ("  Kernel page fault CPU time: %ld.%ld\n", buf -> pr_kftime.tv_sec,
  	buf -> pr_kftime.tv_nsec);
  printf ("  User lock wait time: %ld.%ld\n", buf -> pr_ltime.tv_sec,
  	buf -> pr_ltime.tv_nsec);
  printf ("  Other sleep time: %ld.%ld\n", buf -> pr_slptime.tv_sec,
  	buf -> pr_slptime.tv_nsec);
  printf ("  CPU latency time: %ld.%ld\n", buf -> pr_wtime.tv_sec,
  	buf -> pr_wtime.tv_nsec);
  printf ("  Stopped time: %ld.%ld\n", buf -> pr_stoptime.tv_sec,
  	buf -> pr_stoptime.tv_nsec);
  printf ("  Minor faults: %ld\n", buf -> pr_minf);
  printf ("  Major faults: %ld\n", buf -> pr_majf);
  printf ("  Number of swaps: %ld\n", buf -> pr_nswap);
  printf ("  Input blocks: %ld\n", buf -> pr_inblk);
  printf ("  Output blocks: %ld\n", buf -> pr_oublk);
  printf ("  Messages sent: %ld\n", buf -> pr_msnd);
  printf ("  Messages received: %ld\n", buf -> pr_mrcv);
  printf ("  Signals received: %ld\n", buf -> pr_sigs);
  printf ("  Voluntary context switches: %ld\n", buf -> pr_vctx);
  printf ("  Involuntary context switches: %ld\n", buf -> pr_ictx);
  printf ("  System calls: %ld\n", buf -> pr_sysc);
	printf ("  Characters read/written: %ld\n", buf -> pr_ioch);
	return;
}

/*
*  /proc/pid/status
*/

# 5  
Old 12-11-2012
Login or Register to Ask a Question

Previous Thread | Next Thread

4 More Discussions You Might Find Interesting

1. Solaris

Patching Procedure in Solaris 10 with sun cluster having Solaris zone

Hi Gurus I am not able to find the patching procedure for solaris 10 ( sol10 u11) to latest patchset with sun cluster having failover zones so that same I should follow. Take an instance, there are sol1 and sol2 nodes and having two failover zones like sozone1-rg and sozone2-rg and currently... (1 Reply)
Discussion started by: nick101
1 Replies

2. Solaris

Solaris ssh client hangs when connecting to another Solaris machine

Got a strange problem. I have 4 Solaris servers all configured the same, Solaris 10 x86 update 10. When I try to ssh from one Solaris 10 server to another server ssh hangs. I have an identical server and when I try this everything works fine. The weird thing is if I am root on the server... (1 Reply)
Discussion started by: ccj4467
1 Replies

3. Solaris

root disk mirroring in solaris volume manager for solaris 10

Need a procedure document to do "root disk mirroring in solaris volume manager for solaris 10". I hope some one will help me asap. I need to do it production environment. Let me know if you need any deatils on this. Thanks, Rama (1 Reply)
Discussion started by: ramareddi16
1 Replies

4. Solaris

Unable to login using ssh,telnet onto my solaris machine with solaris 10 installed

Hi, I am unable to login into my terminal hosting Solaris 10 and get the below error message "Server refused to allocate pty ld.so.1: sh: fatal: libc.so.1: open failed: No such file or directory " Is there anyways i can get into my machine and what kind of changes are required to be... (7 Replies)
Discussion started by: sankasu
7 Replies
Login or Register to Ask a Question