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<debug> { print " IsItReallyReallyGone:\n Gone = <$Gone>\n Path = <$Path>\n RtnStr = <$RtnStr>\n"; } if %CommandLine<debug> { 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 <path to backup directory>
             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 <number of 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
      --debug        False
      --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_path [BACKUP]\MyDocsBackup\backup1"

Sample Cobian File, Destination for use with CobianWrapper.pl6:
    %DISKLABEL="BACKUP":\MyDocsBackup\backup1

Sample Cobian Post-backup Event call to CobianWrapper.pl6 (requires USB_Disk_Eject-1.3.0.3.exe):
    Execute and wait: C:\NtUtil\USB_Disk_Eject.exe /REMOVELABEL BACKUP

Suggest Cobian Backup settings:
   For successful rotation, exclude the following:
       desktop.ini
       Thumbs.db
       .dropbox.cache

   --> Tools (pull down)
     --> Options
   General (left Column):
        uncheck: Log new version as error
        uncheck: Check for Updates
   Log (left Column):
        Mail log files
        uncheck: Send as attachment
        When to mail: Mail after every task
   Functionality:
        Show shutdown option on confirmation
   Visuals:
        Show numbers in progress bars
   Advanced:
      Cobian Backup:
         Communications (tab):
             IPC timeout: change from 180_000 to 3_600_000
      Cobian Reflector:
         Process exit timeout (seconds): change from 600 to 1200











Reply via email to