/home/fernape/Projects/lkmonitor/src/procinfo.c

Go to the documentation of this file.
00001 
00002 /*
00003         lkmonitor (Linux Kernel Monitor)
00004 
00005         Application for monitoring and tuning a Linux kernel.
00006 
00007         Copyright (C) 2005-2008  Fernando ApesteguĂ­a
00008 
00009         This program is free software; you can redistribute it and/or
00010         modify it under the terms of the GNU General Public License
00011         as published by the Free Software Foundation; either version 2
00012         of the License, or (at your option) any later version.
00013 
00014         This program is distributed in the hope that it will be useful,
00015         but WITHOUT ANY WARRANTY; without even the implied warranty of
00016         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017         GNU General Public License for more details.
00018 
00019         You should have received a copy of the GNU General Public License
00020         along with this program; if not, write to the Free Software
00021         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00022 */
00023 
00024 /*
00025  * Update widgets in a process specific window
00026 */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <gnome.h>
00033 #include <dirent.h>
00034 #include <errno.h>
00035 #include <glib.h>
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #include "lkmonitor.h"
00040 #include "others.h"
00041 #include "procinfo.h"
00042 #include "update.h"
00043 
00044 #define UNK_STR _("Unknown")
00045 
00050 static int filter (const struct dirent *entry)
00051 {
00052 
00053   if ((strcmp (entry->d_name, ".") == 0) ||
00054       (strcmp (entry->d_name, "..") == 0))
00055     return (0); /*We're not interested in '.' or '..' directories*/
00056 
00057   return(1);
00058 }                       
00059 
00064 static int get_fd_list(const char *path,struct dirent ***filelist)
00065 {
00066         g_assert(path!=NULL);
00067 
00068         int numfich;
00069         
00070         if ((numfich = scandir (path, filelist, &filter, numsort)) == -1)
00071     {
00072       perror ("scandir error");
00073       return (-1);
00074     }
00075         
00076         return(numfich);
00077 }
00078 
00079 
00087 static int get_files_info(const char *path, struct procinfo *pi,
00088                                                                         struct dirent ***file_list,int *numfiles)
00089 {
00090         g_assert(path!=NULL && pi!=NULL);
00091 
00092   GString *files_path=g_string_new(path);
00093 
00094   g_string_append(files_path, "/fd/");
00095 
00096   if((*numfiles=get_fd_list(files_path->str, file_list))<0){
00097         g_warning("Can't read fd directory");
00098         g_string_free(files_path,TRUE);
00099         return -1;
00100   }
00101         
00102         g_string_free(files_path,TRUE);
00103         return 0;
00104 
00105 }
00106 
00107 
00113 static int get_cmdline_info(const char *path, struct procinfo *pi)
00114 {
00115         g_assert(path!=NULL && pi!=NULL);
00116 
00117   gchar *contents;
00118   gsize len;
00119   GString *cmdline_file=g_string_new(path);
00120 
00121   g_string_append(cmdline_file,"/cmdline");
00122   
00123   if((g_file_get_contents(cmdline_file->str,&contents,&len,NULL))==FALSE){
00124         /* Can't read file */
00125         pi->cmdline=g_string_new(UNK_STR);
00126         g_string_free(cmdline_file,TRUE);
00127         g_free(contents);
00128         return -1;
00129   }
00130 
00131         /* We've read the file */
00132         /*
00133          * Parse the file, cause null characters are
00134          * instead blank spaces...
00135          * 
00136          */
00137   {
00138         int i;
00139         char *p;
00140 
00141         p=contents;
00142         for(i=0;i<len;i++){
00143                 if(*p=='\0')
00144                         *p=' ';
00145                 p++;
00146         }
00147 
00148   *(--p)='\0';
00149   }
00150   
00151 
00152   /* Creating the GString */
00153   pi->cmdline=g_string_new(contents);
00154 
00155   /* Cleaning up and returning... */
00156   g_string_free(cmdline_file,TRUE);
00157   
00158   return 0;
00159 
00160 }
00161 
00162 
00168 static int get_env_info(const char *path, struct procinfo *pi)
00169 {
00170         g_assert(path!=NULL && pi!=NULL);
00171 
00172   char *p;
00173   gchar *contents;
00174   gsize len;
00175   GString *env_file=g_string_new(path);
00176 
00177   g_string_append(env_file,"/environ");
00178 
00179 
00180   if((g_file_get_contents(env_file->str,&contents,&len,NULL))==FALSE){
00181         /* Something bad happend... */
00182         pi->env=g_string_new(UNK_STR);
00183         g_string_free(env_file,TRUE);
00184         g_free(contents);
00185         return -1;
00186   }
00187 
00188 
00189 
00190   /* Let's change the ugly NULL characters by \n characters */
00191 {
00192   int i;
00193   p=contents;
00194   for(i=0;i<len;i++){
00195         if(*p=='\0')
00196                 *p='\n';
00197         p++;
00198   }
00199 }
00200  
00201  
00202   pi->env=g_string_new(contents);
00203 
00204   /* Cleaning up... */
00205   g_string_free(env_file,TRUE);
00206   g_free(contents);
00207 
00208   return 0;
00209   
00210 
00211 }
00212 
00213 
00219 static int get_maps_info(const char *path, struct procinfo *pi)
00220 {
00221         g_assert(path!=NULL && pi!=NULL);
00222 
00223   gchar *contents;
00224   GString *maps_file=g_string_new(path);
00225 
00226   g_string_append(maps_file,"/maps");
00227 
00228   if((g_file_get_contents(maps_file->str, &contents,NULL,NULL))==FALSE){
00229         /* Something bad happend */
00230         g_string_free(maps_file,TRUE);
00231         pi->maps=g_string_new("");
00232         g_free(contents);
00233         return -1;
00234   }
00235 
00236   /* We've read the file */
00237 
00238   pi->maps=g_string_new(contents);
00239 
00240   /* Cleaning... */
00241 
00242   g_string_free(maps_file,TRUE);
00243   g_free(contents);
00244 
00245   return 0;
00246 
00247 }
00248 
00254 static int get_vm_info(const char *path,struct procinfo *pi)
00255 {
00256         g_assert(path!=NULL && pi!=NULL);
00257 
00258         gchar *contents;
00259         GString *status_file=g_string_new(path);
00260 
00261         g_string_append(status_file,"/status");
00262 
00263   if((g_file_get_contents(status_file->str, &contents,NULL,NULL))==FALSE){
00264         /* Something bad happend */
00265         g_string_free(status_file,TRUE);
00266         /* Set all the variables to a default value */
00267         strncpy(pi->size,UNK_STR,DEF_SZ);
00268         strncpy(pi->locked,UNK_STR,DEF_SZ);
00269         strncpy(pi->rss,UNK_STR,DEF_SZ);
00270         strncpy(pi->data,UNK_STR,DEF_SZ);
00271         strncpy(pi->stack,UNK_STR,DEF_SZ);
00272         strncpy(pi->exe,UNK_STR,DEF_SZ);
00273         strncpy(pi->lib,UNK_STR,DEF_SZ);
00274         strncpy(pi->state,UNK_STR,DEF_SZ+5);
00275         strncpy(pi->sleepavg,UNK_STR,DEF_SZ/3);
00276         strncpy(pi->threads,UNK_STR,DEF_SZ/3);
00277 
00278         g_free(contents);
00279         return -1;
00280   }
00281 
00282   /* 
00283         * We've read the file 
00284         * Use the find_data_for function to parse the file
00285         */
00286         find_data_for("VmSize: %[^\n]",pi->size,contents);
00287         find_data_for("VmLck: %[^\n]",pi->locked,contents);
00288         find_data_for("VmRSS: %[^\n]",pi->rss,contents);
00289         find_data_for("VmData: %[^\n]",pi->data,contents);
00290         find_data_for("VmStk: %[^\n]",pi->stack,contents);
00291         find_data_for("VmExe: %[^\n]",pi->exe,contents);
00292         find_data_for("VmLib: %[^\n]",pi->lib,contents);
00293         find_data_for("State: %[^\n]",pi->state,contents);
00294         find_data_for("SleepAVG: %[^\n]",pi->sleepavg,contents);
00295         find_data_for("Threads: %[^\n]",pi->threads,contents);
00296 
00297   /* Cleaning... */
00298 
00299   g_string_free(status_file,TRUE);
00300   g_free(contents);
00301 
00302   return 0;
00303 
00304 }
00305 
00312 int get_mm_details(const int pid, struct mm_details *details,
00313                                                         const char *mmregion)
00314 {
00315         g_assert(pid>0 && details!=NULL && mmregion!=NULL);
00316 
00317         /* We use mmregion to make the search */
00318         GString *smaps_file=g_string_new("");
00319         gchar *contents;
00320         char *p;
00321 
00322         /* Construct the path */
00323         g_string_printf(smaps_file,"/proc/%d/smaps",pid);
00324 
00325         if((g_file_get_contents(smaps_file->str,&contents,NULL,NULL))==FALSE){
00326                 /* Something wrong with the file... 
00327                  * So put default values
00328                 */
00329                 strncpy(details->size,UNK_STR,DEF_SZ);
00330                 strncpy(details->rss,UNK_STR,DEF_SZ);
00331                 strncpy(details->sh_clean,UNK_STR,DEF_SZ);
00332                 strncpy(details->sh_dirty,UNK_STR,DEF_SZ);
00333                 strncpy(details->priv_clean,UNK_STR,DEF_SZ);
00334                 strncpy(details->priv_dirty,UNK_STR,DEF_SZ);
00335                 
00336                 /* Cleaning up */
00337                 g_string_free(smaps_file,TRUE);
00338                 g_free(contents);
00339 
00340                 return -1;
00341         }
00342 
00343         /* OK, the file is in the buffer */
00344 
00345         if ((p=strstr(contents,mmregion))!=NULL){
00346                 /* Use the find_data_for function again */      
00347                 find_data_for("Size: %[^\n]",details->size,p);
00348                 find_data_for("Rss: %[^\n]",details->rss,p);
00349                 find_data_for("Shared_Clean: %[^\n]",details->sh_clean,p);
00350                 find_data_for("Shared_Dirty: %[^\n]",details->sh_dirty,p);
00351                 find_data_for("Private_Clean: %[^\n]",details->priv_clean,p);
00352                 find_data_for("Private_Dirty: %[^\n]",details->priv_dirty,p);
00353         }
00354 
00355         /* Clean up ... */
00356 
00357         g_string_free(smaps_file,TRUE);
00358 
00359         return 0;
00360 }
00361 
00369 int get_process_info(const int pid, struct procinfo *pi,
00370                                                         struct dirent ***file_list, int *numfiles)
00371 {
00372         g_assert(pid>0 && pi!=NULL);
00373 
00374   GString *path=g_string_new("/proc/");
00375 
00376   g_string_append(path,(gchar *)lkmonitor_itoa(pid));
00377 
00378   /* Get cmdline info */
00379   if(get_cmdline_info(path->str,pi)!=0)
00380         g_warning("Can't get cmdline info.");
00381 
00382   /* Get environment info */
00383   if(get_env_info(path->str,pi)!=0)
00384         g_warning("Can't get environment info for process");
00385  
00386   /* Get maps info */
00387   if(get_maps_info(path->str,pi)!=0)
00388         g_warning("Can't get memory maps info.");
00389 
00390   /* Get files info */
00391   if(get_files_info(path->str,pi,file_list,numfiles)!=0)
00392         g_warning("Can't get file descriptors info.");
00393 
00394         /* Get VM info and other status file information */
00395         if(get_vm_info(path->str,pi)!=0)
00396                 g_warning("Can't get VM info.");
00397 
00398   /* Cleaning up... */
00399   g_string_free(path,TRUE);
00400   
00401   return 0;
00402 }

Generated on Tue Apr 1 22:52:52 2008 for lkmonitor by  doxygen 1.5.1