Reverting to a previous snapshot has been possible for over a year!!!!! How did I miss that ?? This has for a long time been one of my only real criticisms of LVM and I just discovered that it was quietly committed into the kernel back in 2.6.33
The command used to do the revert is contained within lvconvert. From the lvconvert man page:
--merge
Merges a snapshot into its origin volume. To check if your ker‐
nel supports this feature, look for 'snapshot-merge' in the out‐
put of 'dmsetup targets'. If both the origin and snapshot vol‐
ume are not open the merge will start immediately. Otherwise,
the merge will start the first time either the origin or snap‐
shot are activated and both are closed. Merging a snapshot into
an origin that cannot be closed, for example a root filesystem,
is deferred until the next time the origin volume is activated.
When merging starts, the resulting logical volume will have the
origin's name, minor number and UUID. While the merge is in
progress, reads or writes to the origin appear as they were
directed to the snapshot being merged. When the merge finishes,
the merged snapshot is removed. Multiple snapshots may be spec‐
ified on the commandline or a @tag may be used to specify multi‐
ple snapshots be merged to their respective origin.
A quick check using the command ‘dmsetup targets’ shows that it is definitely in my kernel so I thought I would give it a quick run through and test it lot. I created a testing logical volume and then put some data on it, took a snapshot, changed the data and then reverted to the snapshot. Here is what I did.
Create a new logical volume with a file system and mount it.
[root@titanium ~]# lvcreate -L1G -n lv_test vg_titanium
Logical volume "lv_test" created
[root@titanium ~]# mke2fs -j /dev/vg_titanium/lv_test
mke2fs 1.41.14 (22-Dec-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 262144 blocks
13107 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 33 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@titanium ~]# mkdir /mnt/test
[root@titanium ~]# mount /dev/vg_titanium/lv_test /mnt/test
Create some test data then take a snapshot and create some more test data.
[root@titanium ~]# touch /mnt/test/testdata-$(date +%Y%m%d%H%M%S)
[root@titanium ~]# ls -l /mnt/test/
total 20
drwx------. 2 root root 16384 Sep 19 00:39 lost+found
-rw-r--r--. 1 root root 0 Sep 19 00:39 testdata-20110919003936
[root@titanium ~]# SNAP_NAME="lv_test-snapshot-$(date +%Y%m%d%H%M%S)"
[root@titanium ~]# lvcreate -s /dev/vg_titanium/lv_test -L 1G -n $SNAP_NAME
Logical volume "lv_test-snapshot-20110919003936" created
[root@titanium ~]# touch /mnt/test/testdata-$(date +%Y%m%d%H%M%S)
[root@titanium ~]# ls -l /mnt/test/
total 24
drwx------. 2 root root 16384 Sep 19 00:39 lost+found
-rw-r--r--. 1 root root 0 Sep 19 00:39 testdata-20110919003936
-rw-r--r--. 1 root root 0 Sep 19 00:39 testdata-20110919003937
Here is the actual merge command.
[root@titanium ~]# lvconvert --merge /dev/vg_titanium/$SNAP_NAME
Can't merge over open origin volume
Merging of snapshot lv_test-snapshot-20110919003936 will start next activation.
You will need to deactivate and activate to get the merge to start. You can immediately remount the filesystem as your view of it will be that of the snapshot once the merge has started. Once mounted you can check the data.
[root@titanium ~]# umount /dev/vg_titanium/lv_test
[root@titanium ~]# lvchange -an /dev/vg_titanium/lv_test
[root@titanium ~]# lvchange -ay /dev/vg_titanium/lv_test
[root@titanium ~]# mount /dev/vg_titanium/lv_test /mnt/test
[root@titanium ~]# ls -l /mnt/test/
total 20
drwx------. 2 root root 16384 Sep 19 00:39 lost+found
-rw-r--r--. 1 root root 0 Sep 19 00:39 testdata-20110919003936
As we can see we have reverted to the filesystem at the time we took the snapshot.
Clean up
[root@titanium ~]# umount /dev/vg_titanium/lv_test
[root@titanium ~]# lvremove /dev/vg_titanium/lv_test
Logical volume "lv_test-snapshot-20110919003936" successfully removed
Do you really want to remove active logical volume lv_test? [y/n]: y
Logical volume "lv_test" successfully removed
rmdir /mnt/test
I HATE THE CAPS_LOCK KEY!!!! I don’t like it when people send me messages with full caps and I don’t like accidentally pressing it and then sending messages to other people who then think I am yelling at them. It also wastes too much keyboard space and is in an easy place to accidentally hit. Time to get rid of it.
The following method is for Fedora 15 but will probably work on other Gnome 3 systems.:
Click on the user menu on the top right. Select System Settings
Region and Language -> Layouts -> Options -> Caps Lock key behaviour.
There are several different options but I am going with Disabled for the time being.
Now if I want to yell at someone I need to put in a little more effort but maybe that will make the world a better place
This is quite handy to know if you need to create a new network bond on a live system without disrupting traffic.
First of all create your bond configs in the normal way so that in the event of a reboot it will come back up working. See the Redhat documentation for how to do it in RHEL6.
Now because we cannot just restart the networking to bring that up we need to construct it by hand. Lets say out 2 interfaces we wish to bond are eth3 and eth4 and the bond we are going to create is bond1
- Make sure the bonding driver is loaded by modprobing the module alias you set up in /etc/modprobe/bond1.conf
- Create the bond interface in the /sys filesystem
1
| echo "+bond1" > /sys/class/net/bonding_masters |
- Now that we have an interface we need to enslave the interfaces
1
| ifenslave bond1 eth3 eth4 |
- Lastly we need to start the interface up with the configuration we used in the networking-scripts. Change the ip address and netmask to suit your requirements.
1
| ip addr add 192.168.0.100/24 brd + dev bond1 |
This is just a quick note to save this useful bit of information. I may make in to a script one day or use it in something else.
1
| echo ''|openssl s_client -connect localhost:636 2>/dev/null | openssl x509 -noout -enddate | sed 's/^not.*\=//' |
Small script to run a instance of mysql in my home directory using the binary provided by the OS. Maybe some day I will make it more usable but for the time being it suits my needs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| #!/bin/bash
MYSQL_HOME=$HOME
MYSQL_USER=$USER
MYSQL_PORT=13306
ACTION=$1
if [ $ACTION == 'init' ]; then
echo "initalising new mysql installation at $MYSQL_HOME/var/lib/mysql"
rm -rf $MYSQL_HOME/var/lib/mysql
mkdir -p $MYSQL_HOME/var/lib/mysql $MYSQL_HOME/mysql/data $HOME/var/lib/mysql/tmp
mysql_install_db --user=$MYSQL_USER --datadir=$MYSQL_HOME/var/lib/mysql/data/
cat < $HOME/.my.cnf
[mysqld]
user=$MYSQL_USER
datadir=$MYSQL_HOME/var/lib/mysql/data
log-error=mysqld.log
pid-file=mysqld.pid
socket=$MYSQL_HOME/var/lib/mysql/tmp/mysql.sock
port=$MYSQL_PORT
[client]
user=$MYSQL_USER
socket=$MYSQL_HOME/var/lib/mysql/tmp/mysql.sock
port=$MYSQL_PORT
[safe_mysqld]
log-error=mysqld.log
pid-file=mysqld.pid
port=$MYSQL_PORT
EOT
echo " Done"
elif [ $ACTION == 'start' ];then
echo -n "Starting mysqld as $MYSQL_USER on $MYSQL_PORT"
nohup mysqld_safe &>/dev/null &
echo " Done"
elif [ $ACTION == 'stop' ];then
PID=$(cat $MYSQL_HOME/var/lib/mysql/data/mysqld.pid)
echo -n "Stopping mysql instance [$PID]"
kill `cat $MYSQL_HOME/var/lib/mysql/data/mysqld.pid`
echo " Done"
else
echo "Unknown command '$1'"
fi |
UPDATED SCRIPT:
I decided to update the script and make it less hacky
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
| #!/bin/bash
MYSQL_HOME=$HOME
MYSQL_USER=$USER
MYSQL_PORT=13306
function init {
echo "initalising new mysql installation at $MYSQL_HOME/var/lib/mysql"
rm -rf $MYSQL_HOME/var/lib/mysql
mkdir -p $MYSQL_HOME/var/lib/mysql $MYSQL_HOME/mysql/data $HOME/var/lib/mysql/tmp
mysql_install_db --user=$MYSQL_USER --datadir=$MYSQL_HOME/var/lib/mysql/data/
cat <<EOT > $HOME/.my.cnf
[mysqld]
user=$MYSQL_USER
datadir=$MYSQL_HOME/var/lib/mysql/data
log-error=mysqld.log
pid-file=mysqld.pid
socket=$MYSQL_HOME/var/lib/mysql/tmp/mysql.sock
port=$MYSQL_PORT
innodb_file_per_table
[client]
user=$MYSQL_USER
socket=$MYSQL_HOME/var/lib/mysql/tmp/mysql.sock
port=$MYSQL_PORT
[safe_mysqld]
log-error=mysqld.log
pid-file=mysqld.pid
port=$MYSQL_PORT
EOT
echo " Done"
}
function start {
echo -n "Starting mysqld as $MYSQL_USER on $MYSQL_PORT"
nohup mysqld_safe &>/dev/null &
echo " Done"
}
function stop {
if [ -e $MYSQL_HOME/var/lib/mysql/data/mysqld.pid ]; then
PID=$(cat $MYSQL_HOME/var/lib/mysql/data/mysqld.pid)
echo -n "Stopping mysql instance [$PID]"
kill $PID
echo " Done"
else
echo "mysqld.pid file doesnt exist"
fi
}
function usage {
echo "Unknown command '$1'"
}
function status {
if [ -e $MYSQL_HOME/var/lib/mysql/data/mysqld.pid ]; then
PID=$(cat $MYSQL_HOME/var/lib/mysql/data/mysqld.pid)
ps -p $PID &>/dev/null
RTN=$?
else
RTN=-1
fi
if [ $RTN -eq 0 ]; then
echo "Mysql Running, pid:$PID"
elif [ $RTN -eq 1 ]; then
echo "mysql stopped but pidfile exists"
elif [ $RTN -eq -1 ]; then
echo "Stopped"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
;;
init)
init
;;
*)
echo $"Usage: $0 {start|stop|status|restart|init}"
exit 1
esac |