Clone and Compress LVM Volume to Disk Image

Monday, August 25th, 2025

Clone and Compress LVM Volume to Disk Image

If you need to backup an LVM volume, you can do so by first turning off the virtual machine that is using the volume, and then you can use the dd and gzip utilities to create a copy of the volume to an .img file and compress the image file.  This compressed image file can then be transferred remotely over SSH or HTTP (for fastest results) to another server where it can be restored.

Need More Storage Space for the Backup Image (Optional)?

If you don't have enough storage space on the root LVM volume the main system uses on the host server to handle saving the backup image file to, you can always create a new LVM and then mount it on the host LVM file system to save it there.

These steps are optional:

1.  Create new hard drive in your vm pool using virt-manager and name it temp_storage – you don't need to setup the OS or continue creating the virtual machine

2.  Format and mount this new LVM volume (update vms with your pool's actual name – on my server, it is named vms):

mkfs.ext4 /dev/mapper/vms-temp_storage
mount /dev/mapper/vms-temp_storage /mnt/store

Copy and Compress the LVM

Use the below commands to copy your LVM volume to an img file.  Update the names and the paths as needed.

dd if=/dev/vms/name_of_lvm of=/mnt/store/name_of_lvm.img bs=8M status=progress
gzip name_of_lvm.img -1

Uncompressing and Restoring the LVM

Just decompress the image file and then use the dd command to restore the image to the LVM volume created on the target or restore server.

gunzip name_of_lvm.img.gz
dd if=name_of_lvm.img of=/dev/vms/restore-lvm-name bs=8M status=progress

And you're done 🙂

Restoring Areca Backups

Friday, October 20th, 2023

Restoring Areca Backups

The first step to restoring an Areca backup image is to map the network drives as they were on the computer you made the backup from (if you were using network drives to store the backup).  If you can't remember how the network drives were initially configured or mapped, proceed to the next step, and Areca will eventually tell you which drive is missing.  Once the drives have been remapped as before, and if the backup file is no longer stored on that mapped drive, copy your Areca backup folder (for example, in my case, the folder named 1878606550) to the backup drive location.   

In order to restore an Areca backup archive onto another computer, you need to copy the bcfg file located in the areca_config_backup folder to the Areca workspace directory on the computer you're attempting to restore the files on.  Once you've done that, you can restart Areca, and you'll be prompted to provide the encryption key.  Enter it here.

Assuming the drives exist as they did on the previous computer and the backup folder exists where the backups were being stored, you should be able to view the files within the Archives tab.  Right click on the backup and choose "Recover".  Follow this wizard, and the files will be unencrypted and extracted.   

MongoDB BSON Restore, Converting to JSON, and More MongoDB Helpful Commands

Wednesday, May 25th, 2022

MongoDB Helpful Scripts & Commands

Restoring BSON Backups

The below batch script helps you extract all .gz zipped BSON MongoDB table backup files and then restore these tables to a particular Mongo database easily:

@ECHO ON
SET SourceDir=%~dp0
cd %SourceDir%
mkdir "extracted"
mkdir "extracted\json"
FOR /R %SourceDir% %%A IN ("*.gz") DO "C:\Program Files\7-Zip\7z.exe" x "%%~A" -o"%SourceDir%\extracted"
mongorestore -d {DATABASE_NAME_TO_RESTORE_TABLES_INTO} --host localhost:27017 "extracted"

Converting MongoDB Tables and Data to Proper JSON

If you want to convert MongoDB tables and their data into JSON, you can use the below commands:

mongoexport -d {DATABASE_TO_EXPORT_FROM} --host localhost:27017 -c {TABLE_NAME_TO_EXPORT_CONVERT_INTO_JSON} --jsonArray --pretty -o "%SourceDir%\extracted\json\{TABLE_NAME_BEING_CONVERTED_TO_JSON_NAME}.json"

With older versions of MongoDB, the json file export doesn't actually contain valid JSON. To fix the $date and $numberLong properties which are invalid according to JSON specifications, you can run the below Python 2.7 script:

######################################
# About                              #
######################################

# Author:   Eric Arnol-Martin https://eamster.tk
# Purpose:  Replaces Mongo's Exported DateTime Format with Proper DateTime String Representations for Easier Import for Other Databases / Programming Languages
# Expects:  Mongo JSON Exported Pretty File.  
#			For example, a file produced by a command similar to 
#			"mongoexport -d {db_name} --host localhost:27017 -c {table_name} --jsonArray --pretty -o {table_name}.json"
# Tests:    RegEx Test Link:  https://regexr.com/68l7r
# Outputs:  Creates a copy of the input JSON file with DateTime objects replaced with their proper string representation in the same directory as the original file 
#			with the same file name suffixed with "_NEW" at the end of it.
# Sources:  https://stackoverflow.com/questions/2503413/regular-expression-to-stop-at-first-match
#			https://stackoverflow.com/questions/159118/how-do-i-match-any-character-across-multiple-lines-in-a-regular-expression

######################################
# Imports                            #
######################################

import re
from os.path import exists
import fileinput


######################################
# Actual Program                     #
######################################

path = input ("Enter path or name of file to parse: ")
prevPiece = None
content_new = ""
boolReplaceFromNextLine = False
boolHandlingLong = False

if exists(path):
	# Clear new file
	b = open(path + "_NEW", "w+")
	b.close()
	count = 0
	recordCount = 0

	for line in fileinput.input(files=path):
		count = count + 1
		if '"$date":' in line: 
			content_new = content_new[0:content_new.rindex('{')] + line.replace('"$date": {', '').replace('"$date":', '').replace('\n', '').strip();
			boolReplaceFromNextLine = True
		else:
			if boolReplaceFromNextLine:
				if '"$numberLong":' in line:
					content_new = content_new + line.replace('"$numberLong":', '').replace('\n', '').strip();
					boolReplaceFromNextLine = True
					boolHandlingLong = True
				else:
					if boolHandlingLong:
						content_new = content_new + line.replace('}', '').strip();
						boolReplaceFromNextLine = True
						boolHandlingLong = False
					else:
						boolReplaceFromNextLine = False
						content_new = content_new + line.replace('}', '').strip() + '\n';
			else:
				content_new = content_new + line		
		
		if line == '},\n' and content_new:
			recordCount = recordCount + 1
			b = open(path + "_NEW", "a+")
			b.write(content_new)
			b.close()	
			content_new = ""
			print('Record ' + str(recordCount) + ' processed... adding it to the file...')
			
		prevPiece = line
	
	if content_new:
		b = open(path + "_NEW", "a+")
		b.write(content_new)
		b.close()	
		content_new = ""
		recordCount = recordCount + 1
		print('Record ' + str(recordCount) + ' processed... adding it to the file...')

Save iptables on Shutdown and Restart, and Restore on Boot

Tuesday, October 6th, 2015

Save iptables Rules on Shutdown, Restore on Boot

When your server shutsdown (halts), reboots, or enters runlevel 1, your iptables configuration is automatically wiped and reset.  Packages such as iptables-persistent supposedly help with this problem, but unless you save your rules manually, the rules are never saved automatically when the system reboots. 

I've wanted to truly persist my iptables, so I decided to change their package to always save the iptables rules when the system reboots, halts, or enters runlevel 1 automatically.  The rules are then restored when the system boots to runlevels 2-5.  This means that your iptables configuration will persist forever.  This may not be desired, but if I ban an IP address permanently, I always want it to be banned.

If you'd like to use this modified version of iptables-persistent so that your rules are automatically saved on shutdown, you can install it by running the below commands:

sudo apt-get remove iptables-persistent
sudo dpkg -r iptables-persistent
wget http://dinofly.com/files/linux/iptables-persistent_0.5.8_all.deb
sudo dpkg --install iptables-persistent_0.5.8_all.deb

Use at your own risk.  If you do something stupid, it will persist until you can clear it!

The above package was tested in Ubuntu 12.04 x86, Ubuntu 12.04 x64, Ubuntu 14.04 x86, Ubuntu 14.04 x64, and Ubuntu 15.04 x64.  Should work on other debian operating systems as well.