[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
managment of a full file partition
Date: Tue, 7 Feb 89 10:43:14 N
From: baechler%elma.epfl.ch@CUNYVM.CUNY.EDU
Several weeks ago, I encountered the following problem:
the partition of our server machine was full and we didn't know what
room occupied our different directories. I looked at the documentation and
I didn't find any useful tool. But the problem was really annnoying and
slowed down our work. Finally I decided to write a such tool by myself.
I guess that many of us have written some version of this tool. Mine is
included below.
To use it, invoke the Show Disk Usage command on the root directory of
the part of the hierarchy that you are interested in. It prints output
like the following:
Show Disk Usage1 0SYS:CONCORDIA;
Total records Local records Pathname
1014 (100%) 319 (31%) CHUCK:>sys>r7-2>concordia>
639 (63%) 635 (63%) CHUCK:>sys>r7-2>concordia>doc>
4 (0%) 2 (0%) CHUCK:>sys>r7-2>concordia>doc>patch>
2 (0%) CHUCK:>sys>r7-2>concordia>doc>patch>concordia-doc-9>
29 (3%) 23 (2%) CHUCK:>sys>r7-2>concordia>locking>
6 (1%) 3 (0%) CHUCK:>sys>r7-2>concordia>locking>patch>
3 (0%) CHUCK:>sys>r7-2>concordia>locking>patch>lock-simple-19>
22 (2%) 1 (0%) CHUCK:>sys>r7-2>concordia>standin>
21 (2%) 2 (0%) CHUCK:>sys>r7-2>concordia>standin>patch>
19 (2%) CHUCK:>sys>r7-2>concordia>standin>patch>standins-1>
5 (0%) 2 (0%) CHUCK:>sys>r7-2>concordia>patch>
3 (0%) CHUCK:>sys>r7-2>concordia>patch>concordia-13>
The display is a depth-first traversal. At each new level the pathname
is indented a bit more. All of the subdirs of a given directory are
displayed in largest-first order. The "Total records" line is the
number of records included in the entire subhierarchy, including the
directory itself. The "Local records" shows the record count of the
files that reside in that directory (not including subdirectories).
This column is blank if the entry has no subdirs. All percentages are
in terms of the total number of records in the root's subtree, since I
usually use this to look for big payoffs.
I use the command to keep snapshots of the disk usage.
Show Disk Usage Chuck:> :Output Destination file c:>disk-usage-880210.text
I can then compare the current listing with the previous one to see
where the free records have gone.
Another sometimes-useful command, Show Total Records, is included as
well. Unlike Show Disk Usage, it takes an "accordion wildcard" pathname
so you can restrict the search to files that match some pattern. One
interesting use is to compare:
Show Total Records host:>my-project-dir>**>*.lisp.*
with
Show Total Records host:>my-project-dir>**>*.lisp.newest
to see how much space is used by old versions of your files.
;;; -*- Mode: LISP; Package: USER; Base: 10; Syntax: Common-lisp -*-
(cp:define-command (com-show-disk-usage :command-table 'user)
((path 'pathname :default (send (send (send (si:pathname-history-first-pathname)
:translated-pathname)
:directory-pathname-as-file)
:pathname-as-directory)))
(disk-usage-sorted (send path :new-pathname :name :wild :type :wild :version :wild)))
(defun disk-usage-sorted (dir)
(labels ((collect-data (dir)
(tv:alter-progress-note-text (format nil "Scanning ~A" dir))
(loop for (path . props) in (fs:directory-list dir :sorted)
when (getf props :directory)
collect (multiple-value-list
(collect-data (send path :pathname-as-directory)))
into subdir-info
when (getf props :length-in-blocks)
sum (getf props :length-in-blocks) into shallow-space
finally
(let ((deep-space 0))
(loop for (subdir-path deep shallow) in subdir-info
do
(incf deep-space (+ deep shallow)))
(return (values dir deep-space shallow-space subdir-info))))))
(let ((data (multiple-value-list
(tv:noting-progress-alterable-note ("Scanning hierarchy")
(collect-data (send dir :translated-pathname)))))
total-space-used)
(labels ((print-data (entry level)
(destructuring-bind (path deep shallow subdir-info)
entry
(formatting-row ()
(formatting-cell ()
(format t "~6D (~D%)"
(+ shallow deep)
(round (* (/ (+ shallow deep) total-space-used) 100))))
(formatting-cell ()
(if subdir-info
(format t "~6D (~D%)"
shallow
(round (* (/ shallow total-space-used) 100)))
(format t " ")))
(formatting-cell ()
(format t "~v@T~A"
level
(send (send path :directory-pathname-as-file)
:pathname-as-directory))))
(loop for sub in (sort (copy-list subdir-info)
#'> :key #'(lambda (e)
(+ (second e) (third e))))
do
(print-data sub (+ level 2))))))
(destructuring-bind (nil deep shallow nil)
data
(setq total-space-used (+ deep shallow))
(fresh-line)
(terpri)
(formatting-table ()
(formatting-column-headings (t :underline-p t)
(formatting-cell ()
"Total records")
(formatting-cell ()
"Local records")
(formatting-cell ()
"Pathname"))
(print-data data 0)))))))
(cp:define-command (com-show-total-records :command-table 'user)
((paths '((sequence pathname))))
(loop for path in paths
for (f r b) =
(multiple-value-list
(loop for (pn . props) in (fs:directory-list path)
count pn into files
when pn
sum (getf props :length-in-bytes 0) into bytes
when pn
sum (getf props :length-in-blocks 0) into records
finally (return (values files records bytes))))
sum f into files
sum r into records
sum b into bytes
finally (format t "~&~:D files, total records used = ~:D (~:D bytes)"
files records bytes)))