4

I'm trying to create a tar of a large LVM volume onto multiple external drives. That part is solved. Now, because it is a LONG process, I'd like a progress bar. From the excellent articles here, I've gotten close.

The issue is that the PV bar quits after the first volume fills up. I'd like PV to continue updating after disks are swapped. Does someone have an idea about how to approach this?

Here's what I've tried. I think the problem is in the last line of code. I'm not sure this strategy will actually work with multi-volumes.

Code ExtBackup.sh:

#!/bin/sh

changedisk()
{
# This routine is called when tar runs out of disk space
# It simply waits for operator to change and mount disks
# then updates the file handle with a new volume number.
echo "Change disks now!" 
read -p "Press <enter> when new disk is mounted. ..." NULL
echo ""

# Update the file name with the new volume number
name=`expr $TAR_ARCHIVE : '\(.*\)-.*'`
echo ${name:-$TAR_ARCHIVE}-Vol$TAR_VOLUME.tar >&$TAR_FD
}

###########
## MAIN  ##
###########

# Test for recursive call to change disks
if [ "$1" = 'changedisk' ]; then 
        changedisk
        exit 0;
fi

# If this is initial call, set SIZE to calculate bytes in source    
SIZE=`du -sb *Folder_Name* | cut -f 1`

# Now TAR it, using Multi-volume option and pipe through PV for progress bar
tar -cM -F 'sh ExtBackup.sh changedisk' *Folder_Name* | \
pv -s ${SIZE} > LVMBackup-$(date +%m-%d-%y)-Vol1.tar

1 Answer 1

1

Alright, it took me some time to understand what tar -F actually does (is that documented anywhere at all? I just ended up reading the source), but I think I came up with a pretty good solution for you.

Since pv doesn't support pretending that a certain progress has already been made, I needed to replace it with a similar tool called bar (available in Debian under that name, or see its hideous homepage).

The solution I found passes the data of all additional volumes through a named pipe (FIFO) to inject the bar invocation into the stream. To avoid printing each volume's progress bar in a new line, I use 'tput' to move the cursor back up after each volume.

In your code, you would replace the last line in changedisk() with the following. (This is a bit hacky for the sake of brevity; just customize it once you get the idea)

tput cuu1 >&2 # clear previous progress bar
(cat somefifo | bar -ns \
    --size "$SIZE" \
    --completed $(((${TAR_VOLUME}-1)*${VOLSIZE})) \
    > ${name:-$TAR_ARCHIVE}-Vol$TAR_VOLUME.tar) &
echo somefifo >&$TAR_FD

And replace the pv invocation in the last line of your script with bar -ns --size ${SIZE}.

For this to work, you need to put export in front of the SIZE definition, and of course have executed mkfifo somefifo at some point beforehand. Make sure you also secure that FIFO's permission bits. You might also want to consider using mktemp to safely create a temporary pipe instead. Depends on your scenario, I guess.

I used an as-of-yet undefined variable $VOLSIZE that should expand to the size of your volumes in bytes. I'm not sure how this is determined in your setup. Maybe you need to do something more elaborate here, like keeping track of the cumulative sum of all the previous volume sizes.

2
  • The -F option aka. --info-script or --new-volume-script is well-documented on the [GNU manual page here][1] for the tar binary under Section 9.6.1 (Archives Longer than One Tape or Disk). [1]: gnu.org/software/tar/manual/html_node/… Jun 24, 2023 at 20:26
  • True! Back in 2014, pre version 1.28, the manpage apparently was generated based on the CLI usage help and did not contain any further explanation of the option. The manual did provide more info at that time already, though. Jun 25, 2023 at 13:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .