summarylogtreecommitdiffstats
path: root/pacman-cage
blob: 6c16f588269138dfddd837164fee409955c9bf8f (plain)
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/bash
#
#   pacman-cage
#
#   Copyright (c) 2002-2006 by Andrew Rose <rose.andrew@gmail.com>
#   I used Judds pacman-optimise as a framework.
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
#   USA.
#

myver='2.9.9'
dbroot="/var/lib/pacman"
pacmandb="/var/lib/pacman.db"
pacmanlog=$(pacman -Qv | grep "Log File" | cut -d ":" -f2)

usage() {
        echo "pacman-cage $myver"
        echo "usage: $0 [pacman_db_root]"
        echo
        echo "pacman-cage creates a loopbacked filesystem in a contigious file."
        echo "This will give better response times when using pacman"
        echo
}

die() {
        echo "pacman-cage: $*" >&2
        exit 1
}

die_r() {
        rm -f /tmp/pacman.lck
        die $*
}

if [[ "$1" != "" ]]; then
        if [[ "$1" == "-h" || "$1" == "--help" ]]; then
                usage
                exit 0
        fi
        dbroot=$1
fi

[[ $(id -u) != 0 ]] && die "You must be root to cage the database"

# added by wain: make sure kernel support loop device
if ! zcat /proc/config.gz | grep "BLK_DEV_LOOP=\(y\|m\)" >/dev/null; then
        die "please enable loop device support in kernel (BLK_DEV_LOOP=y)"
fi

# make sure pacman isn't running
[[ -f /tmp/pacman.lck ]] && die "Pacman lockfile was found.  Cannot run while pacman is running."
# make sure pacman.db hasnt already been made
[[ -f $pacmandb ]] && die "$pacmandb already exists!"
[[ ! -d $dbroot ]] && die "$dbroot does not exist or is not a directory."

# don't let pacman run while we do this
touch /tmp/pacman.lck

# write to pacman.log
echo "[ $(date '+%Y-%m-%d %H:%M ')] Pacman-cage [cmd] >> Starting and preparing pacman database caging process ..." >> $pacmanlog

# step 1: sum the old db
echo "==> md5sum'ing the old database..."
find $dbroot -type f | sort | xargs md5sum >/tmp/pacsums.old

echo "==> creating pacman.db loopback file..."
dd if=/dev/zero of=$pacmandb bs=1M count=150 &>/dev/null

echo "==> creating ext2 -O dir_index -b 1024 on $pacmandb..."
mkfs.ext2 -F -O dir_index -b 1024 -m 0 $pacmandb &>/dev/null

echo "==> creating temporary mount point /mnt/tmp-pacman.."
mkdir /mnt/tmp-pacman

echo "==> mounting pacman.db to temporary mount point..."
mount -o loop $pacmandb /mnt/tmp-pacman

echo "==> copying pacman database to temporary mount point..."
cp -a /var/lib/pacman/. /mnt/tmp-pacman

echo "==> unmounting temporary mount point..."
umount /mnt/tmp-pacman

echo "==> removing temporary mount point..."
rmdir /mnt/tmp-pacman

echo "==> moving old /var/lib/pacman to /var/lib/pacman.bak..."
[[ -d /var/lib/pacman.bak ]] && rm -rf /var/lib/pacman.bak
mv /var/lib/pacman /var/lib/pacman.bak

echo "==> creating new pacman db mount point @ $dbroot..."
mkdir $dbroot

echo "==> Mounting new pacman db..."
mount -o loop $pacmandb $dbroot

echo "==> md5sum'ing the new database..."
find $dbroot -type f | sort | xargs md5sum >/tmp/pacsums.new

echo "==> checking integrity..."
diff /tmp/pacsums.old /tmp/pacsums.new &>/dev/null
if [[ $? != 0 ]]; then
        # failed, move the old one back into place
        umount $dbroot
        rm $pacmandb
        mv $dbroot.bak $dbroot
        echo "[ $(date '+%Y-%m-%d %H:%M ')] Pacman-cage [cmd] >> Something went wrong. Old database was restored." >> $pacmanlog
        die_r "integrity check FAILED, reverting to old database"
fi

# Replaced by wain: mount is now in /etc/rc.d/pacmandb daemon
#echo "==> Updating /etc/fstab to reflect changes..."
#echo "$pacmandb $dbroot ext2 loop,defaults 0 0" >> /etc/fstab

rm -f /tmp/pacman.lck /tmp/pacsums.old /tmp/pacsums.new

echo "[ $(date '+%Y-%m-%d %H:%M ')] Pacman-cage [cmd] >> Pacman database has been caged." >> $pacmanlog
echo
echo "Finished.  Your pacman database has been caged!.  May the speedy pacman be with you."
echo

exit 0