[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Automatic process: What's the problem?
Date: Mon, 9 Nov 1992 13:05 EST
From: jiang@lia.di.epfl.ch (Tao JIANG)
[... Message Removed ...]
We decided to do something similar in addition to our normal backup. We
set up a background process which would wake up at a certain time every
night and make adjustments to a mirror directory so that it looked just
like our primary directory. The code is at the end of this message.
Craig Lanning <CLanning@trc.scra.org>
Grumman Data Systems
North Charleston, SC
---------------------------------------------------------------------
;;; -*- Mode: LISP; Syntax: Common-Lisp; Package: USER; Base: 10 -*-
#||
This function takes a source pathname, a destination pathname, and a
time of day. It then creates a background process which, everyday
at TIME, will traverse the source tree and adjust the destination
tree to be a mirror backup.
Example:
(update-mirror-backup "FOO:>" "BAR:>foo>" "3:00")
Every night at 3:00am the process named "Mirror [FOOBAR]" will
wakeup and adjust "BAR:>foo>" to be a mirror image of "FOO:>". Note
that none of the files are marked as being backed up.
||#
(defun UPDATE-MIRROR-BACKUP (source destination time)
(setq source (fs:parse-pathname source))
(setq destination (fs:parse-pathname destination))
(labels ((UPDATE-WAIT (time) (> (time:get-universal-time) time))
(UPDATE-TREE-INTERNAL (sroot droot)
(let ((add 0) (remove 0) sfiles dfiles)
(setf sfiles (cdr (fs:directory-list sroot :sorted)))
(setf dfiles (cdr (fs:directory-list droot :sorted)))
(loop for (path . props) in sfiles
;; move new files to backup directory
unless (getf props :directory)
do (let ((dpath (fs:merge-pathnames droot path)))
(unless (probe-file dpath)
(copy-file path dpath)
(incf add))))
;; remove non-existent files from backup directory
(loop with expunge? = nil
for (path . props) in dfiles
unless (probe-file (fs:merge-pathnames sroot path))
do (if (getf props :directory)
(let ((dfile (fs:merge-pathnames
(format nil "~A>" (send path :raw-name))
droot)))
(incf remove (delete-tree dfile))
(setq expunge? t))
(progn (send path :delete) (setq expunge? t)))
finally (when expunge? (send droot :expunge)))
;; recurse into subdirectories
(loop for (path . props) in sfiles
when (getf props :directory)
do (let* ((nsroot (send path :pathname-as-directory))
(ndroot (fs:merge-pathnames
(format nil "~A>" (send path :raw-name))
droot)))
(unless (probe-file (send ndroot :directory-pathname-as-file))
;; create the destination directory if needed
(send ndroot :create-directory))
(multiple-value-bind (sadd sremove)
(update-tree-internal nsroot ndroot)
(incf add sadd) (incf remove sremove))))
(values add remove)))
(DELETE-TREE (root)
(let ((count 0) (files (cdr (fs:directory-list root :sorted))))
(loop for (path . props) in files
do (if (getf props :directory)
(let ((dpath (fs:merge-pathnames
(format nil "~A>" (send path :raw-name))
root)))
(incf count (delete-tree dpath)))
(progn (send path :delete) (incf count))))
(send root :expunge)
(send (send root :directory-pathname-as-file) :delete)
count))
(UPDATE-TREE (sroot droot time)
(loop for next-time = (time:parse-universal-time time) doing
(process:process-wait (format nil "Wait for ~\\time\\" next-time)
#'update-wait next-time)
(tv:notify nil "Mirror Backup: Begin")
(multiple-value-bind (add remove) (update-tree-internal sroot droot)
(tv:notify nil "Mirror Backup: ~D files copied" add)
(tv:notify nil "Mirror Backup: ~D files removed" remove))
(tv:notify nil "Mirror Backup: Complete")))
)
(process:process-run-function
`(:name ,(format nil "Mirror [~A~A]" (send source :host)
(send destination :host))
:restart-after-reset t)
#'update-tree source destination time)
))