On 1/7/24 06:16, Parrot Raiser wrote:
What's the reason behind the request?
Hi Parrot,
The reason is to eliminate the Optimizer as a
source of weird problems.
I have written a wrapper for Cobian Backup/Reflector
that rotates backup sets. Cobain has is own database
to keep track of backup sets, but it falls apart when
you are rotating several removable drives as the target.
Removable drives in rotation defeats ransomware.
So, my program locates the drive letter the target
resides on based on drive label (it will do letter too),
then counts the backup sets. If these sets exceed
the limit of sets, I remove the oldest.
For example maximum backup sets is set to 4. Then backup4
gets erased, backup3 gets renamed to backup4, backup2
gets renamed to backup3, backup1 gets renamed to backup2.
At this point there should be no backup1. And I check for
it:
sub DirectoryExists( Str $DirPath --> Bool ) { return
"$DirPath".IO.d.Bool; } # $Full DirPath format is `H:\MyDocsBackup`
Problem: sometimes DirectoryExists lies about
backup1 existing. Failure to rotate has to do with
something is the backup set that won't move. These
are typically system files. When I find them, I enter
into Cobian's exclude mask:
desktop.ini
Thumbs.db
.dropbox.*
.dropbox.cache
sessions.jsoniz4
events
~*
~$
python.exe
python3.exe
I have traced this down to the "size" of backup1 too.
A directory in backup1 that refuses to move in
a large backups, will move in a simple test task.
Now to workaround the issue of DirectoryExists not
always returning the correct answer, I have written
my own code for it:
sub IsItReallyReallyGone( Str $Path --> Bool ) {
# checks to see if a file or directory is really gone and not stuck in cache
my Bool $Gone = False;
my Str $RtnStr = "";
# Note: "File Not Found" is sent to the STDERR
$RtnStr = RunCmd Q[dir ] ~ $Path ~ Q[ /A 2>&1];
if $RtnStr.lc.contains( "file not found" ) { $Gone = True ; }
# if %CommandLine { print " IsItReallyReallyGone:\n Gone
= <$Gone>\n Path = <$Path>\n RtnStr = <$RtnStr>\n"; }
if %CommandLine { print " IsItReallyReallyGone: $Path is
$Gone\n"; }
return $Gone;
}
And I flush a lot(same as Linux's "sync"):
sub FlushDriveCache( Str $Drive ) {
my Str $SingleLetter = $Drive.uc.substr( 0..0 );
my Str $RtnStr = "";
print " Flushing " ~ $SingleLetter ~ "'s drive cache\n";
$RtnStr = RunCmd "powershell.exe Write-VolumeCache " ~
$SingleLetter, True;
}
And IsItReallyReallyGone is dead nuts totally, repeatable accurate.
If backup1 is really not gone, a flush and a second delete usually
does the trick. (I can repeat this double erase with Windows
Explorer. First time through it coughs on certain files.
Second time through, it gets them all.)
sub FastRmdir( $DirPath ) {
RunCmd( "del /f/s/q " ~ $DirPath ~ " > nul" );
RunCmd( "rmdir " ~ $DirPath ~ " /S /Q" );
}
Now if backup1 still exists and is not rotated, Cobian keeps
writing to it and eventually the target drive fill up,
meaning no more new backups.
And that is a problem, especially with trying to get my
customer's to actually read their backup reports that
Cobian eMails them (and me, but I only check them
periodically and only as a courtesy).
So in summary, the issue is probably a cache issue with
Raku's IO commands not keeping up with what Windows
is doing. Disabling the Optimizer would remove that
issues as a problem. And Raku's IO commands needs
some work when dealing with large amounts of a data
in cache.
Sorry for being so long winded.
-T
My program's help file:
>raku CobianWrapper.pl6 --help
Welcome to CobianWrapper.pl6
CobianWrapper.pl6 usage:
CobianWrapper.pl6
--backup_path
Drive letter or partition label plus path to backup directory.
for a label, surround the label with square brackets [].
Note: the backup directory name must end in a 1
--rotates
--nokill
nokill will disable the killing of programs known to be
Shadow Copy (VSS) unfriendly
--debug
--help
Defaults:
--backup_path [BACKUP]\MyDocsBackup\backup1
--rotates 2
--nokill False
--debugFalse
--help False
For example
raku C:\NtUtil\CobianWrapper.pl6 --rotates 6 --backup_path
A:\MyDocsBackup\n\backup1
raku C:\NtUtil\CobianWrapper.pl6 --rotates 4 --backup_path
[BACKUP]\MyDocsBackup\backup1
more? (y/n) y
Sample Cobian Pre-backup Event call to CobianWrapper.pl6:
Note: Events, Command Line is currently not working Cobian Reflector as
of 1.0.0
Execute and wait: "C:\Program Files\Rakudo\bin\raku.exe"
"C:\NtUtil\CobianWrapper.pl6 --rotates 20 --backup_pat