LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-12-2003, 11:14 AM   #1
welby
LQ Newbie
 
Registered: Jul 2003
Posts: 7

Rep: Reputation: 0
Bash Scripting - Waiting for a certain amount of data


Short version: Anyone know a way to script a file copy so that x amount of data copies to a location, flushes, and the copy resumes to gather x amount of data again?

We're implementing a DVD system to backup fiels on remote servers. The way the DVD system archives data is this:

Data is put into a cache directory of the local machine, then moves the data onto DVD. If the amount of data going into the cache outstips the amount of data going out of the cache, the copy times out. Due to disk space limitations, I've only got about 20GB of cache space available to give the DVD system, but I've got 80+ GB of data on various servers.

The directory structure is too fragmented to parse the directories in a reference file. (18,000 directories on server, for example) I've figured out the while statement (code follows) to check the parameters of the cache, but can't figure a way to limit the initial data copy until the system is done archiving.

Script:

#!/bin/sh

SERVERLIST_FILENAME="serverlist.txt"

DELAY_THRESHOLD=0

DELAY_TIME="60s"

DELAYED_EVENTS=99999

poll_for_mmparam_delayedevents() {
echo I am polling right now.... I am waiting a really long time...
DELAYED_EVENTS=`mmparam TEST | grep "Number of delayed events:" | awk '{print $5}'`
sleep $DELAY_TIME
}

for BACKUP_PATH in `cat $SERVERLIST_FILENAME | grep -v "^#"`
do
SOURCE_PATH=`echo $BACKUP_PATH | awk -F : '{print $1}'`
DESTINATION_PATH=`echo $BACKUP_PATH | awk -F : '{print $2}'`
echo I am backing up $SOURCE_PATH to $DESTINATION_PATH

cp -RPd $SOURCE_PATH $DESTINATION_PATH

# Wait in loop until delayed events are all processed. Only
# then should we move on to copy the next server.
while [ $DELAYED_EVENTS -gt $DELAY_THRESHOLD ]
do
poll_for_mmparam_delayedevents
done

# reset to avoid a potential race-condition
DELAYED_EVENTS=99999
done


Contents of the serverlist file (typically)

/mnt/SERVER1/data/Images:/BACKUP/mount/SERVER1/full/data/Images
/mnt/SERVER1/data/HOME:/BACKUP/mount/SERVER1/full/data/HOME
/mnt/SERVER1/data/APPS:/BACKUP/mount/SERVER1/full/data/APPS
/mnt/SERVER1/data/ADMIN:/BACKUP/mount/SERVER1/full/data/ADMIN

Ideas are welcomed.
 
Old 08-12-2003, 04:28 PM   #2
crabboy
Moderator
 
Registered: Feb 2001
Location: Atlanta, GA
Distribution: Slackware
Posts: 1,823

Rep: Reputation: 120Reputation: 120
How about a C Program?

I just hacked up this C program that I think will do what you need.

It takes three parameters. The source directory, the destination directory and the size you want to pause at. IMPORTANT: Make sure that the dest directory is not in the source tree.

When the program has copied x amount of data to the destination it will pause until it gets a SIG_HUP. The script that is pulling the data will have to delete the files it has already processed and call "kill -HUP <pid>" to restart the copy.

Source directory should probably be relative (but not required). Destination does not have to be. Try it out on a smaller temporary tree.

Is this even close to what you are looking for?

Code:
#include <stdio.h>
#include <pwd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <signal.h>

#define BUFFER_SIZE 2048

int currentSize = 0;

static void sig_hup()
{
   if ((int) signal( SIGHUP, SIG_IGN) == -1 )
      perror("Signal Error");

   if ((int)signal( SIGHUP, sig_hup) == -1 )
      perror("Signal Error");

   return;
}

int copyfile( char * src, char * dest )
{

   int fdIn = 0;
   int fdOut = 0;
   int iReadSize = 0;
   int iWriteSize = 0;
   char szBuffer[ BUFFER_SIZE + 1 ];

   fdIn = open( src, O_RDONLY );
   fdOut = creat( dest, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );

   while ( (iReadSize = read( fdIn, szBuffer, BUFFER_SIZE )) > 0 )
   {
      iWriteSize = write( fdOut, szBuffer, iReadSize );

   } // end while

   close( fdIn );
   close( fdOut );
}

void listdir(char * directory, char * destdir, int maxsize)
{
    struct stat FileInfo;
    char name[MAXPATHLEN];
    struct stat dirinfo;
    struct dirent * files;
    DIR * dirin;
    int len, a, log;
    char newdir[MAXPATHLEN];
    char newfile[MAXPATHLEN];

    if (lstat(directory, &dirinfo) < 0)
    {
        perror (directory);
        return;
    }
    if (!S_ISDIR(dirinfo.st_mode))
        return;


    if ((dirin = opendir(directory)) == NULL)
    {
        perror(directory);
        return;
    }
    while ((files = readdir(dirin)) != NULL)
    {
        sprintf(name, "%s/%s", directory, files -> d_name);
        if (lstat(name, &FileInfo) < 0)
            perror(name);


        if ( S_ISDIR( FileInfo.st_mode ) &&
             strcmp(files -> d_name, ".") != 0 &&
             strcmp(files -> d_name, "..") != 0 )
        {
           sprintf( newdir, "%s/%s/", destdir, name );
           mkdir(  newdir, S_IRWXU | S_IRWXG | S_IRWXO );

           listdir(name, destdir, maxsize);

        }
        else if ( strcmp(files -> d_name, ".") != 0 &&
                  strcmp(files -> d_name, "..") != 0 )
        {
            if ( (FileInfo.st_size + currentSize) > maxsize )
            {
               pause();
               currentSize = 0;
            }
            currentSize += FileInfo.st_size;
            sprintf( newfile, "%s/%s", destdir, name );
            copyfile( name, newfile );

        }

    }
    closedir(dirin);
}


main(int argc, char * argv[])
{

   char szInitialDirectory[MAXPATHLEN];
   char newdir[MAXPATHLEN];

   if ((int)signal(SIGHUP, sig_hup ) == -1 )
      perror("Signal Error");

   strcpy( szInitialDirectory, argv[1] );

   sprintf( newdir, "%s/%s/", argv[2], argv[1] );
   mkdir(  newdir, S_IRWXU | S_IRWXG | S_IRWXO );

   listdir( szInitialDirectory, argv[2], atoi(argv[3]) );

}
 
Old 08-14-2003, 10:36 AM   #3
welby
LQ Newbie
 
Registered: Jul 2003
Posts: 7

Original Poster
Rep: Reputation: 0
You sir, are the man.

Thanks!
 
Old 05-11-2004, 01:12 PM   #4
Linh
Member
 
Registered: Apr 2003
Posts: 178

Rep: Reputation: 30
To crabboy

Hi crabboy. Thank you for showing me the link.

I put the program into my Linux box as you have showned using the
program name, source dir, dest dir, and the size but it just hang there.

1) What does the program suppose to do with regard to the source
directory, destination directory and size ?

2) Does the size refers to a size of a file, or a size of a directory ?

3) Please show me how to run this program.

root:/home# ./directory_2 /home /home/linh 200
 
Old 05-11-2004, 01:21 PM   #5
crabboy
Moderator
 
Registered: Feb 2001
Location: Atlanta, GA
Distribution: Slackware
Posts: 1,823

Rep: Reputation: 120Reputation: 120
You probably don't want to use this program as-is. It was writtin for a specific task of copying files and waiting for a signal.
You probably just want to use the listdir() method removing the desitination dir from the parameter list and also remove:
Code:
          if ( (FileInfo.st_size + currentSize) > maxsize )
            {
               pause();
               currentSize = 0;
            }
also remove call to copyfile() all the signal stuff and the mkdir call.

Last edited by crabboy; 05-11-2004 at 01:22 PM.
 
Old 05-11-2004, 02:04 PM   #6
Linh
Member
 
Registered: Apr 2003
Posts: 178

Rep: Reputation: 30
reply to crabboy

Hi crabboy. Thank you for your help. I modified the code as you have suggested. I then ran it using ./directory_2 /home/ee. This gives correct result, but when I used ./directory_2 /home or ./directory_2 /home/
it did not list any file but the stuff shown below continuously and then it resulted in a segmentation fault.

name = Flash
name = .
name = ..
name = Flash
name = .
name = ..
name = Flash
name = .
name = ..

===================================

Code:
#include <stdio.h>
#include <pwd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <signal.h>

#define BUFFER_SIZE 2048

int currentSize = 0;


/*******************************************************/

void listdir(char * directory, int maxsize)
{
    struct stat FileInfo;
    char name[MAXPATHLEN];
    struct stat dirinfo;
    struct dirent * files;
    DIR * dirin;
    int len, a, log;
    char newdir[MAXPATHLEN];
    char newfile[MAXPATHLEN];

    if (lstat(directory, &dirinfo) < 0)
    {
        perror (directory);
        return;
    }
    if (!S_ISDIR(dirinfo.st_mode))

    if ((dirin = opendir(directory)) == NULL)
    {
        perror(directory);
        return;
    }
    while ((files = readdir(dirin)) != NULL)
    {
        printf ("name = %s\n", files -> d_name);
        sprintf(name, "%s/%s", directory, files -> d_name);
        if (lstat(name, &FileInfo) < 0)
            perror(name);


        if ( S_ISDIR( FileInfo.st_mode ) &&
             strcmp(files -> d_name, ".") != 0 &&
             strcmp(files -> d_name, "..") != 0 )
        {
           sprintf( newdir, "%s/%s/", name );
           mkdir(  newdir, S_IRWXU | S_IRWXG | S_IRWXO );

           listdir(name, maxsize);

        }
        else if ( strcmp(files -> d_name, ".") != 0 &&
                     strcmp(files -> d_name, "..") != 0 )
        {
          currentSize += FileInfo.st_size;
          sprintf( newfile, "%s", name );
        }

    }
    closedir(dirin);
}

/*******************************************************/

main(int argc, char * argv[])
{

   char szInitialDirectory[MAXPATHLEN];
   char newdir[MAXPATHLEN];

   strcpy( szInitialDirectory, argv[1] );

   sprintf( newdir, "%s/%s/", argv[2], argv[1] );
   mkdir(  newdir, S_IRWXU | S_IRWXG | S_IRWXO );

   listdir( szInitialDirectory, atoi(argv[3]) );

}
 
Old 05-11-2004, 10:58 PM   #7
crabboy
Moderator
 
Registered: Feb 2001
Location: Atlanta, GA
Distribution: Slackware
Posts: 1,823

Rep: Reputation: 120Reputation: 120
Try this:

Code:
#include <stdio.h>
#include <pwd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <signal.h>

#define BUFFER_SIZE 2048

int currentSize = 0;


/*******************************************************/

void listdir(char * directory )
{
    struct stat FileInfo;
    char name[MAXPATHLEN];
    struct stat dirinfo;
    struct dirent * files;
    DIR * dirin;
    int len, a, log;

    if (lstat(directory, &dirinfo) < 0)
    {
        perror (directory);
        return;
    }
    if (!S_ISDIR(dirinfo.st_mode))
    {
        perror(directory);
        return;
    }

    if ((dirin = opendir(directory)) == NULL)
    {
        perror(directory);
        return;
    }
    while ((files = readdir(dirin)) != NULL)
    {
/*
        printf ("name = %s\n", files -> d_name);
*/
        sprintf(name, "%s/%s", directory, files -> d_name);
        if (lstat(name, &FileInfo) < 0)
            perror(name);


        if ( S_ISDIR( FileInfo.st_mode ) &&
             strcmp(files -> d_name, ".") != 0 &&
             strcmp(files -> d_name, "..") != 0 )
        {
           listdir(name );

        }
        else if ( strcmp(files -> d_name, ".") != 0 &&
                     strcmp(files -> d_name, "..") != 0 )
        {
           printf("%s\n", name );
        }

    }
    closedir(dirin);
}

/*******************************************************/

main(int argc, char * argv[])
{

   char szInitialDirectory[MAXPATHLEN];

   strcpy( szInitialDirectory, argv[1] );

   listdir( szInitialDirectory );

}
 
Old 05-12-2004, 07:47 AM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,287

Rep: Reputation: 173Reputation: 173
what about using 'dd' ?



billy
 
Old 05-12-2004, 09:36 AM   #9
Linh
Member
 
Registered: Apr 2003
Posts: 178

Rep: Reputation: 30
reply

Thank you crabboy for your help.

I ran the new code and it works. I have not compared the new code with the old one. Can you quickly tells me what changed you have made ?
 
Old 05-12-2004, 10:43 AM   #10
crabboy
Moderator
 
Registered: Feb 2001
Location: Atlanta, GA
Distribution: Slackware
Posts: 1,823

Rep: Reputation: 120Reputation: 120
The segfault was caused by this code:
Code:
    if (!S_ISDIR(dirinfo.st_mode))

    if ((dirin = opendir(directory)) == NULL)
    {
        perror(directory);
        return;
    }
The opendir was being skipped and the readdir was casuing the segfault.

I also cleaned up some other stuff that didn't have to be there.
 
Old 05-12-2004, 12:13 PM   #11
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
@crabboy: I was wondering, is there a reason why you did not leave the signal handler empty like this?
Code:
static void sig_hup() { }
(if so, why?)
 
Old 05-12-2004, 12:33 PM   #12
crabboy
Moderator
 
Registered: Feb 2001
Location: Atlanta, GA
Distribution: Slackware
Posts: 1,823

Rep: Reputation: 120Reputation: 120
It could have been left blank, but I usually add the if blocks as standard practice just in case I want to add some code in the signal handler later.
 
Old 05-12-2004, 12:40 PM   #13
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
OK. Thanks.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
HP laserjet 6p stalls with large amount of data simjii Mandriva 0 11-10-2005 03:32 PM
calculate amount of data transferred to certain ip addresses dtra Linux - Software 0 11-07-2005 07:57 PM
How to find the amount of data downloaded connected to a network ananthbv Programming 2 10-30-2005 12:25 AM
bash script suggestions for waiting for ssh -L iggymac Programming 4 03-22-2005 07:04 PM
How to count amount of data btwn iface and IPAddr krizzz Linux - Networking 1 10-20-2004 07:11 PM


All times are GMT -5. The time now is 08:57 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration