From: hardym@nic.cerf.net (Mike Hardy)
Newsgroups: comp.unix.large,comp.unix.admin
Subject: Filesystem Activity Statistics
Date: 12 Jan 1993 00:43:56 GMT
Organization: CERFnet Dial n' CERF Customer Group
Distribution: world
NNTP-Posting-Host: nic.cerf.net


The following program will traverse a directory tree to gather 
statistics about all files in that tree.  The goal is to get
an understanding of file activity on a server and to determine the
utility of using hierarchical storage management for servers in
general.  I am interested in anyone who would run this program
against their server to help us gather information about the
general state of file activity in the real world.  It has been
tested on Sun, Ultrix, RS/6000, SGI and Unicos platforms.  I ask
that it be run on your server(s) and the output be redirected to a file
and sent to me via email.  I will gather the statistics and
post a review of what I learn to comp.arch.storage.  Any suggestions
on improvements are appreciated.  I would ask that it be run at a
high enough level in your directory to provide information about
user generated and stored data, as opposed to system files.

Run this at your own risk.  You might want to run it a night!

Thanks for any help given.  I will post a complete summary after
responses come in.

Mike Hardy
(619) 455-3757
hardym@sdsc.edu

-------- cut here ----------

#define SECONDSINDAY 60 * 60 * 24	/* Seconds in a day */
#define NOTIN30 SECONDSINDAY * 30 	/* Seconds in 30 days */
#define NOTIN90 SECONDSINDAY * 90	/* Seconds in 90 days */
#define NEVERUSED 0			/* Time diff for files never used */
#define calc_percent(a) (int)(((float)a/(float)totalfiles)*100)

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>

#ifdef sun
#include <sys/time.h>
#endif

#ifdef mc68000
#include <netat/compat.h>
#endif

/* global counter to survive recursion */

int totalfiles = 0;
long totalage = 0;
int neverused = 0;
int notin30 = 0;
int notin90 = 0;
int since30 = 0;
int since90 = 0;
int active = 0;
int numdirs = 0;

main(argc, argv)
int argc;
char **argv;
{
	int i;

	if (argc == 1)
		printf("usage: scan [directory_name]\n");
	for(i=1;i<argc;i++){
		walkdir(argv[i]);
		}

	if (numdirs == 0) exit();

	printf("Number of directories scanned: %d\n", numdirs);
	printf("Total files: %d\n",totalfiles);

	printf("Files never been used:\t\t\t%d\tpercent: %d\n", 
		neverused, calc_percent(neverused));

	printf("Files that are active:\t\t\t%d\tpercent: %d\n",
		active,calc_percent(active));

	printf("Files not used in last 30 days:\t\t%d\tpercent: %d\n",
		notin30, calc_percent(notin30));

	printf("Files not used in last 90 days:\t\t%d\tpercent: %d\n", 
		notin90, calc_percent(notin90));

	printf("Files not used after 30 days old:\t%d\tpercent: %d\n", 
		since30, calc_percent(since30));

	printf("Files not used after 90 days old:\t%d\tpercent: %d\n", 
		since90, calc_percent(since90));

	i = (int)(((float)totalage/(float)totalfiles));
	printf("Average file age:\t%d days\n", i);
	
}

/* recursive function to traverse a directory tree while gathering
file stats */	

int walkdir(dirname)
char *dirname;
{
	int diff;
	int diffnow;
	DIR *dirp;
	struct dirent *dp;
	struct stat statbuf;
	struct stat *bufaddr = & statbuf;
	char pathname[256];

	if ((dirp = opendir(dirname)) == NULL){
		perror("walkdir opendir");
		printf("Bad directory: %s\n", dirname);
		return;
		}

	numdirs++;	

	while ((dp = readdir(dirp)) != NULL){
		pathname[0] = NULL;

		if((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, "..")))
			continue;
		strcat(pathname,dirname);
		strcat(pathname,"/");
		strcat(pathname,dp->d_name);

		if (lstat(pathname, bufaddr) != NULL){
			perror("walkdir stat");
			printf("pathname is %s\n",pathname);
			}
			
		if (S_ISDIR(bufaddr->st_mode))
			walkdir(pathname);
		else{
			totalfiles++;

			/* determine time from last time data was
			   modified until current time		 */

			diff = bufaddr->st_atime-bufaddr->st_mtime;

			/* determine time from last access to now */

			diffnow = time(0) - bufaddr->st_atime;

			if((diff == NEVERUSED) && (diffnow > NOTIN30))
				neverused++;
			if(diffnow < NOTIN30) 
				active++;
			if(diffnow > NOTIN30)
				notin30++;
			if(diffnow > NOTIN90)
				notin90++;
			if((diff < NOTIN30) && (diffnow > NOTIN30))
				since30++;
			if((diff < NOTIN90) && (diffnow > NOTIN30))
				since90++;

			totalage+=(((float)(time(0)-bufaddr->st_mtime))/
				  (float)(SECONDSINDAY));
		}

	}

	closedir (dirp);
}


Newsgroups: comp.unix.large