Apache2 Rewritemap

Filed Under (Sysadmin) by Amandine on 16-02-2011

I love apache mod_rewrite. I often fight with it, but if you really want it you can do whatever you want. This time I wanted to find a way to call a file named after the called subdomain. I have a website called www.yellow-sub.net, and there is some subdomains like the-beatles.yellow-sub.net, john-lennon.yellow-sub.net and so on for each part of the website (That’s a SEO consideration in the beginning). I have only one virtual host for that website because I find it easier to manage like that, and I didn’t want to put the logic in the files for some reasons (and because working with rewrite rules is fun).

This is what I want :

  • you call -> you get
  • www.yellow-sub.net -> index.php?page=somepage
  • the-beatles.yellow-sub.net -> index.php?page=somepage-the-beatles
  • blahblah.yellow-sub.net -> index.php?page=somepage-blahblah

The page parameter will in fact call a different page with name “somepage-blahblah.html”, and I wanted it to work for every single subdomain (if it doesn’t exist it will anyway be redirected to www home page)

The closest way I found was to use %{HTTP_HOST} in my rewriterule :

RewriteCond %{HTTP_HOST} !^www\.yellow-sub\.net$ [NC]
RewriteRule ^/$ /index.php?page=somepage-%{HTTP_HOST} [L]

But this way I had to name my files somepage-the-beatles.yellow-sub.net.html instead of somepage-the-beatles.html, wich is not so bad but quite annoying when I want to copy that from beta (different domain name) to live or from live to beta.

So I found the Rewritemap parameter in the apache documentation website. And That’s just an amazing new feature I didn’t know about : it will let you do whatever you want with your rewrite rules! I let you read the manual page, It’s well written and I won’t explain something already well explained : See that Rewritemap doc

I used the last MapType : External Rewriting Program that allows you to write your own script in whatever programming language you fancy, taking stdin and writing to stdout. Mine is very simple, in bash :

#!/bin/bash
while read line; do
  echo $line |cut -d. -f1
done;

I guess that’s a good practive to Keep It Simple, Stupid, as advised in the manual, cause it will be running as apache child, not called when needed. You can test it by giving it something to process :

$ echo the-beatles.yellow-sub.net |/etc/apache2/scripts/subdomain.sh
the-beatles
$ /etc/apache2/scripts/subdomain.sh
blabla.yellow-sub.net # this is what I wrote
blabla # this is what he said
hgzsfver.erg.erg.reg.ezefg                  
hgzsfver
^C

To use it in you Virtualhost section :

Rewritemap subdomain prg:/etc/apache2/scripts/subdomain.sh
RewriteCond %{HTTP_HOST} !^www\.yellow-sub\.net$ [NC]
RewriteRule ^/$ /index.php?page=somepage-${subdomain:%{HTTP_HOST}} [L]

Don’t be messy with the interesting part ${subdomain:%{HTTP_HOST}}, I sillily wrote a % instead of the $ and spent half an hour to figure it out! (no errors anywhere, the script was launched, it just didn’t work at all).

Reload apache to watch it running now :

 xxxx ?        Ss     0:00 /usr/sbin/apache2 -k start
xxxxx ?        S      0:00  \_ /usr/sbin/apache2 -k start
xxxxx ?        S      0:00  \_ /usr/sbin/apache2 -k start
xxxxx ?        S      0:08  |   \_ /usr/bin/php5-cgi
xxxxx ?        Ss     0:00  |   \_ /usr/bin/php5-cgi
xxxxx ?        S      0:02  |   |   \_ /usr/bin/php5-cgi
xxxxx ?        S      0:00  \_ /bin/bash /etc/apache2/scripts/subdomain.sh
xxxxx ?        Sl     0:46  \_ /usr/sbin/apache2 -k start
xxxxx ?        Sl     0:48  \_ /usr/sbin/apache2 -k start

You can watch it in action using the Rewritelog :

xxx.xxx.xxx.xxx - - [17/Feb/2011:08:39:50 +0100] [the-beatles.yellow-sub.net/sid#c85408][rid#1017528/initial] (5) map lookup OK: map=subdomain key=the-beatles.yellow-sub.net -> val=the-beatles

And now my files are just called the way I wanted to :)
I have to say, I love this feature more because I can imagine a lot of new functions in my rewriterules than because it solved my problem, for which I had other options anyway (not as sexy ones, but solutions though.)

The question now is : it is safe? What are the risks of using such a script within apache? If you have anything to say about that, please tell me :)

Have fun with mod_rewrite!

How to resolv .42 domains

Filed Under (Sysadmin) by Amandine on 29-12-2010

I’m sure you heard of the new unofficial domain registry 42registry, who let you register domains like something.42. If you didn’t, go on there website and read, cause I found this very interesting, funny, and it made me want to try :)

So, after registering sysadmandine.42 domain name, I tried to surf on it. But I didn’t want to spend time to configure a secured but open bind on one of my servers, so I opted for the easy way : my local computer is on Ubuntu, Ubuntu is perfectly able to provide me a bind, so let’s go :

$ sudo aptitude install bind9

Then one line of config like they say on the 42registry website :

$ sudo vim /etc/bind/named.conf.default-zones

add :

zone "42" IN {
type forward;
forwarders {91.191.147.246; 91.191.147.243; 79.143.243.129; 178.20.71.2; 217.174.201.33; 83.169.77.115;};
}

restart bind (surprisingly, just reload didn’t do it) :

$ sudo /etc/init.d/bind9 restart

Check that it’s working :

$ dig @localhost www.sysadmandine.42

(you have to see a ANSWER section id it’s working)

And then tell your system to use it :

$ sudo vim /etc/resolv.conf

Put this on the first line :

nameserver 127.0.0.1

That’s it ! Now you just have to open your firefox or any other browser (be careful with chrome or chromium though, ther’s a trick to make it work with those ones, check the 42registry website to know how.), and try some domains !
* http://www.sysadmandine.42/ (of course)
* http://nic.42/
* I couldn’t find more websites in .42, do you know some?

Add disk space to a .img disk image (for use with xen for example)

Filed Under (Sysadmin) by Amandine on 13-08-2010

Sometimes, you need more space on a virtual machine disk than you thought in the beginning. Hopefully, if your domU disk is in a .img file, you can do it quite easily (you can do it easily with lvm partition too, even if it’s a different method). Here’s how to do it, as root of course :

- Check your partitions in your domU :

df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/xvda2             10G  706M  8.8G   8% /
varrun                2.1G   44K  2.1G   1% /var/run
varlock               2.1G     0  2.1G   0% /var/lock
udev                  2.1G   16K  2.1G   1% /dev
devshm                2.1G     0  2.1G   0% /dev/shm

- create empty file of the size we want to add : (10gb here)

dd if=/dev/zero of=/xen/temp_expand bs=1024k count=10000

- stop your domU

xm shutdown mydomU

- backup img files

cp -a /xen/domains/mydomU /xen/domains/mydomU-bak

- add the empty file to the img file :

cat /xen/temp_expand >> /xen/domains/mydomU/disk.img

You can repeat this step as many times as you need

- tell the filesystem to check and adapt its size :

resize2fs -f /xen/domains/mydomU/disk.img

- restart your domU

xm create -c mydomU.cfg

- check in your domU that everything is ok

df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/xvda2             30G  711M   28G   3% /
varrun                2.1G   44K  2.1G   1% /var/run
varlock               2.1G     0  2.1G   0% /var/lock
udev                  2.1G   20K  2.1G   1% /dev
devshm                2.1G     0  2.1G   0% /dev/shm

Voila! Your disk is now bigger :)

You can also use this method to create a brand new blank disk image, and add it as a new disk for you domU :

dd if=/dev/zero of=/xen/domains/mydomU/otherdisk.img bs=1024k count=150000

or

cat /xen/temp_expand >> /xen/domains/mydomU/otherdisk.img

add the new disk (xvda3) to your /etc/xen/mydomU.cfg :

disk        = [
                  'tap:aio:/xen/domains/mydomU/swap.img,xvda1,w',
                  'tap:aio:/xen/domains/mydomU/disk.img,xvda2,w',
                  'tap:aio:/xen/domains/mydomU/otherdisk.img,xvda3,w',
              ]

after rebooting you domU, check if the new disk is available :

fdisk -l /dev/xvda3

Disk /dev/xvda3: 125.8 GB, 125829120000 bytes
255 heads, 63 sectors/track, 15297 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x00000000

Disk /dev/xvda3 doesn't contain a valid partition table

You’re now free to create your filesystem on this disk, and to mount it wherever you want!

$ mkfs.ext3 /dev/xvda3
$ mkdir /mysql
$ mount /dev/xvda3 /mysql/
$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/xvda2             30G  711M   28G   3% /
varrun                2.1G   44K  2.1G   1% /var/run
varlock               2.1G     0  2.1G   0% /var/lock
udev                  2.1G   20K  2.1G   1% /dev
devshm                2.1G     0  2.1G   0% /dev/shm
/dev/xvda3            117G  188M  111G   1% /mysql

This Howto was made under Ubuntu Hardy, Xen 3.2

Apache2 mod_rewrite and %{REQUEST_FILENAME}

Filed Under (Sysadmin, Tips) by Amandine on 23-02-2010

I’m trying to develop a new website to increase my php object oriented skills. For this new website, I want every request for any url that doesn’t match a actual file on the disk to be redirected to index.php (to handle parameters in fact). Easy with apache2 rewrite rules :

         RewriteCond %{REQUEST_FILENAME} !-f
         RewriteCond %{REQUEST_FILENAME} !-d
         RewriteCond %{REQUEST_FILENAME} !-l                                                                                                                                                                              
         RewriteRule ^/(.*)$         /index.php?rt=$1 [L,QSA]

This means : if the requested file is not a real file, and isn’t a directory, and isn’t a symlink, then redirect to index.php.

I was really surprised to discover that it doesn’t work. Though, everybody seems to use this syntax ! I checked my apache version : Apache/2.2.9 (Debian), nothing special with this one I guess.
To understand what Apache was doing with my rewrites, I activated the rewrite log :

         RewriteLog /var/log/apache2/rewrite.log                                                                                                                                                                      
         RewriteLogLevel 5

Here’s what I got (the interesting part, cause I got a looot more !) :

[blah blah blah] (2) init rewrite engine with requested uri /toto.htm
[blah blah blah] (3) applying pattern '^/(.*)$' to uri '/toto.htm'
[blah blah blah] (4) RewriteCond: input='/toto.htm' pattern='!-f' => matched
[blah blah blah] (4) RewriteCond: input='/toto.htm' pattern='!-d' => matched
[blah blah blah] (4) RewriteCond: input='/toto.htm' pattern='!-l' => matched
[blah blah blah] (2) rewrite '/toto.htm' -> '/index.php?rt=toto.htm'

So apaches verifies only ‘/toto.htm’ and not the whole path for “%{REQUEST_FILENAME}”? I thought though it was the whole path… let’s verify in the doc.
From http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html, by habit (cause I used apache 2.0 a lot more than apache 2.2 from now on) :

REQUEST_FILENAME : The full local filesystem path to the file or script matching the request.

Hmm. But I use apache version 2.2, so what do they say here http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html :

REQUEST_FILENAME : The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI.

Ow.

REQUEST_URI : The resource requested in the HTTP request line. (In the example above, this would be “/index.html”.)

Ok, I understand, I use virtual hosts (like everybody, uh?), so the real syntax for my needs is :

         RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
         RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
         RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-l                                                                                                                                                                              
         RewriteRule ^/(.*)$         /index.php?rt=$1 [L,QSA]

This works even if it doubles the “/” between each variable (one / at the end of DOCUMENT_ROOT, and another at the beginning of REQUEST_FILENAME).

Here’s the rewrite log showing that it works :

[blah blah blah] (2) init rewrite engine with requested uri /toto.htm                                                                          
[blah blah blah] (3) applying pattern '^/(.*)$' to uri '/toto.htm'
[blah blah blah] (4) RewriteCond: input='/path/to/documentroot//toto.htm' pattern='!-f' => not-matched
[blah blah blah] (1) pass through /toto.htm

Now I can disable this log if I want to keep space on my disk.

I must admit I read the description for REQUEST_FILENAME in apache2.2 several times before noticing that it was just the answer… too used to read too fast! Thanks to this old post that made me re-read slower ! ;)

My top 20 linux favourite commands

Filed Under (Sysadmin) by Amandine on 12-02-2010

Here’s my linux favourite commands, by type :

Scripting
1. egrep : aaah… if I had to keep only one, this would be the one I’d choose… can’t spend 10 minutes without using it.
2. sed : because I always need to replace something by something else 10 times on each line in huge files
3. xargs : helps me avoid the for loop, shorter to write, easier to remember and understand when you find it in history
4. awk : for me the most difficult one to use, but I so know that it can do just what I want that I always take the time.

System
5. kill : ha ha, makes me feel I’m powerful
6. ps fauxww : makes me think I can watch everything that’s happening in real time. Like watching 10 movies at the same time.
7. aptitude : I like his way of telling me everything of what he’s doing… so chatty !
8. dstat : this one is really good : tells me a lot of things and with colors, I think he just knows what I’m looking for each time I call him.

Network
9. ssh : is it necessary to say something about it? without him I’d be nothing.
10. telnet : I like the raw output, no interpretation, he’s stupid and this is sometimes really appreciable
11. host : simple tool for so great usefulness, even the basic usage is perfect
12. nmap : I looove knowing everything about hosts I can’t access…
13. tcpdump : really useful when you really dont understand what’s happening.
14. netstat : nmap from the inside. Feels like a treasure hunt sometimes.
15. mtr : seems just easy and fast, but also gives a lot of interesting information.

Tools
16. vim : makes me save so much time
17. screen : How did they live before screen? And I use only a small amount of its potential…

Storage
18. fdisk : boring in the begenning, fun once you know it by heart
19. sfdisk : really handy to mirror a disk partitionning scheme
20. mdadm : I love mdadm. Just love it, don’t know why.

htpasswd encryption

Filed Under (Sysadmin) by Amandine on 12-02-2010

I was wondering how crypt does the encryption of passwords. Once I needed to compare two .htpasswd files, I was quite sure that both had the same password for the same user, but the encrypted strings didn’t match. I tried to regenerate the encrypted string several times, and here’s what I got :

$ htpasswd -nb someuser somepwd
someuser:qQD5GYrJQSIwk
$ htpasswd -nb someuser somepwd
someuser:zD9H4NFRuDjk6
$ htpasswd -nb someuser somepwd
someuser:IK572FjeWHPYw
$ htpasswd -nb someuser somepwd
someuser:O2UkOjX3ynZCU
$ htpasswd -nb someuser somepwd
someuser:9hPT7IR/CN7MA

So, how does it work? How is it possible to compare a password with its encrypted version when you can’t be sure to have the same encryption string each time you encrypt it?
I googled and found that it has something to do with the “salt”. the salt seems to be the 2 first letters of the string, and the password is generated considering those. To be sure, I generated the same password enough times to see :

for i in `seq 1000`; do htpasswd -nb someuser somepwd >> htpasswdtest; done;
sort htpasswdtest

After looking closely to the sorted file, I can say that every time the first 2 letters are identical, the second part of the encrypted string is also identical.

To try to generate a password with a specified salt, you can use the perl crypt function :

perl -le 'print crypt("somepwd", "qQ")'
qQD5GYrJQSIwk

And then you can see that this comand outputs exactly the same string as the htpasswd had generated above !
Mystery solved ! ;)

Pound

Filed Under (Sysadmin) by Amandine on 05-11-2009

Pound is a wonderful tool. It does just what you want, and does it good. Well, most of the time actually. Let me present it.

Pound is made by a Swiss company named Apsis GmbH (http://www.apsis.ch/), and its purpose is to achieve 3 goals :
- reverse proxy
- load balancing
- HTTPS front-end

You don’t need to use all 3 features, but you might need it anyway. Don’t assume it can do other things : No caching, no webserver, no acceleration. Just what it’s meant for.

Read the rest of this entry »

More loop devices

Filed Under (Sysadmin) by Amandine on 30-10-2009

I have this very special server at work : a sunfire x4200 8 core 8GB RAM
To use the full given power, I tried to install xen on ubuntu, but it were freezing all the time. It seems to be a “TAP” problem, but I couldn’t fix it.
So I tried a Debian 5.0.3 dom0, and the problem is slightly different : now the domU won’t find its drives if I use “tap:aio”.
Ok, go back to the old “file:” driver.
This one is using loop devices to enable the drives, and only 8 default loop devices are enabled on debian (/dev/loop0 to /dev/loop7). As I want 7 domU, and at least 2 drives for each one (root and swap), I need more than 8 of these.
Here’s how to add more loop devices :
On Debian and ubuntu loop is a module, and you can specify the number of loop devices you want in /etc/modules. Replace :

loop

by

loop max_loop=64

(64 for example)

Then you have to disable the module :

rmmod loop

and re-enable it :

modprobe loop

But the new devices won’t append automatically for sure, so if you don’t see them in /dev/loop*, you can make them appear this way :
Edit /sbin/MAKEDEV and change :

        loop)
                for part in 0 1 2 3 4 5 6 7
                do
                        makedev loop$part b 7 $part $disk
                done
                ;;

By:

        loop)
                for part in `seq 0 63`
                do
                        makedev loop$part b 7 $part $disk
                done
                ;;

And execute

$ MAKEDEV loop

For me this step didn’t work either, so I had to create it really by hand :

for i in $(seq 0 63); do
    mknod -m0660 /dev/loop$i b 7 $i
    chown root.disk /dev/loop$i
done

Raid1 to Raid5

Filed Under (Sysadmin) by Amandine on 20-10-2009

My new HDD has just arrived ! 1 more terabyte to play with :D
Now the funny part begins : here’s what I already have in my computer :
- 1 x 500GB for all my operating systems
- 2 x 1TB RAID1 for my documents

$ cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 sdb1[1] sdc1[0]
      976759936 blocks [2/2] [UU]
     
unused devices: <none>

My documents partition is full, so I want to switch from 2 x 1TB RAID1 to 3x 1TB RAID5.
I thought it would be easy, as I could read here and there, that 4 command could do the trick :

- stop the RAID1 /dev/md0 array :

$ mdadm --stop /dev/md0

- create the raid5 with only 2 disks in place of the old raid1 :

$ mdadm --create /dev/md0 -l5 -n2 /dev/sdb1 /dev/sdc1

- add the third HDD :

$ mdadm --add /dev/md0 /dev/sdd1

- and use all the available space :

$ mdadm --grow /dev/md0 -n3

But ! Because it wouldn’t have been fun if it were too easy, the first step didn’t work :

$ mdadm --stop /dev/md0
mdadm: fail to stop array /dev/md0: Device or resource busy

Anything I could try made this work (–force, recovery root shell, runlevel 1, degrade the array, kill all my processes…).

The reason, I guess (no, I’m sure), is that I created a lvm partition on that raid array, and this is what prevents me from stopping the array. So considering this, I wanted to try something different, this was the plan :
1) degrade the raid1 array so keep the data on only 1 disk
2) create a raid5 array on the 2 other disks
3) move my lvm partition on that new array
4) delete the lvm physical volume from the old raid1
5) stop (finally) the old array
6) add the last disk to the raid5
7) grow everything to fit (physical volume, logical volume and filesystem which is reiserfs)

Let’s give it a try
1) degrade the raid1 array so keep the data on only 1 disk

$ mdadm /dev/md0 --fail /dev/sdc1
mdadm: set /dev/sdc1 faulty in /dev/md0
$ mdadm /dev/md0 -r /dev/sdc1
mdadm: hot removed /dev/sdc1
$ cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 sdb1[1]
      976759936 blocks [2/1] [_U]
     
unused devices: </none><none>

2) create a raid5 array on the 2 other disks

$ mdadm --create /dev/md1 -l5 -n2 /dev/sdc1 /dev/sdd1
mdadm: /dev/sdc1 appears to be part of a raid array:
    level=raid1 devices=2 ctime=Fri May  8 20:34:01 2009
Continue creating array? y
mdadm: array /dev/md1 started.

3) move my lvm partition on that new array
The hard part !
3.1) initialize the partition on the raid5 array for use by LVM

$ pvcreate /dev/md1
  Physical volume "/dev/md1" successfully created

3.2) add the new physical volume to the docs volume group

$ vgextend vgdocs /dev/md1
  Volume group "vgdocs" successfully extended
$ pvdisplay
  --- Physical volume ---
  PV Name               /dev/md0
  VG Name               vgdocs
  PV Size               931,51 GB / not usable 3,12 MB
  Allocatable           yes (but full)
  PE Size (KByte)       4096
  Total PE              238466
  Free PE               0
  Allocated PE          238466
  PV UUID               rhBfur-zaKN-UBpx-C1lj-LZK0-6TRX-impxD2
   
  --- Physical volume ---
  PV Name               /dev/md1
  VG Name               vgdocs
  PV Size               931,51 GB / not usable 3,12 MB
  Allocatable           yes
  PE Size (KByte)       4096
  Total PE              238466
  Free PE               238466
  Allocated PE          0
  PV UUID               rDkJvJ-xtnW-dAmQ-TtXR-311H-qayQ-7wxLEE

3.3) Move the data from md0 to md1 (This step takes a long time.)

$ pvmove -v -i 10 /dev/md0 /dev/md1
    Finding volume group "vgdocs"
    Archiving volume group "vgdocs" metadata (seqno 5).
    Creating logical volume pvmove0
    Moving 238466 extents of logical volume vgdocs/lvdocs
    Found volume group "vgdocs"
    Updating volume group metadata
    Creating volume group backup "/etc/lvm/backup/vgdocs" (seqno 6).
    Found volume group "vgdocs"
    Found volume group "vgdocs"
    Suspending vgdocs-lvdocs (252:0) with device flush
    Found volume group "vgdocs"
    Creating vgdocs-pvmove0
    Loading vgdocs-pvmove0 table
    Resuming vgdocs-pvmove0 (252:1)
    Found volume group "vgdocs"
    Loading vgdocs-pvmove0 table
    Suppressed vgdocs-pvmove0 identical table reload.
    Loading vgdocs-lvdocs table
    Resuming vgdocs-lvdocs (252:0)
    Checking progress every 10 seconds
  /dev/md0: Moved: 0,1%
...
  /dev/md0: Moved: 100,0%
    Found volume group "vgdocs"
    Found volume group "vgdocs"
    Loading vgdocs-lvdocs table
    Suspending vgdocs-lvdocs (252:0) with device flush
    Suspending vgdocs-pvmove0 (252:1) with device flush
    Found volume group "vgdocs"
    Found volume group "vgdocs"
    Found volume group "vgdocs"
    Resuming vgdocs-pvmove0 (252:1)
    Found volume group "vgdocs"
    Resuming vgdocs-lvdocs (252:0)
    Found volume group "vgdocs"
    Removing vgdocs-pvmove0 (252:1)
    Found volume group "vgdocs"
    Removing temporary pvmove LV
    Writing out final volume group after pvmove
    Creating volume group backup "/etc/lvm/backup/vgdocs" (seqno 8).

$ pvdisplay
  --- Physical volume ---
  PV Name               /dev/md0
  VG Name               vgdocs
  PV Size               931,51 GB / not usable 3,12 MB
  Allocatable           yes
  PE Size (KByte)       4096
  Total PE              238466
  Free PE               238466
  Allocated PE          0
  PV UUID               rhBfur-zaKN-UBpx-C1lj-LZK0-6TRX-impxD2
   
  --- Physical volume ---
  PV Name               /dev/md1
  VG Name               vgdocs
  PV Size               931,51 GB / not usable 3,12 MB
  Allocatable           yes (but full)
  PE Size (KByte)       4096
  Total PE              238466
  Free PE               0
  Allocated PE          238466
  PV UUID               rDkJvJ-xtnW-dAmQ-TtXR-311H-qayQ-7wxLEE

3.4) Remove md0 physical volume from volume group

$ vgreduce vgdocs /dev/md0
  Removed "/dev/md0" from volume group "vgdocs"
$ pvdisplay
  --- Physical volume ---
  PV Name               /dev/md1
  VG Name               vgdocs
  PV Size               931,51 GB / not usable 3,12 MB
  Allocatable           yes (but full)
  PE Size (KByte)       4096
  Total PE              238466
  Free PE               0
  Allocated PE          238466
  PV UUID               rDkJvJ-xtnW-dAmQ-TtXR-311H-qayQ-7wxLEE
   
  "/dev/md0" is a new physical volume of "931,51 GB"
  --- NEW Physical volume ---
  PV Name               /dev/md0
  VG Name              
  PV Size               931,51 GB
  Allocatable           NO
  PE Size (KByte)       0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               rhBfur-zaKN-UBpx-C1lj-LZK0-6TRX-impxD2

4) delete the lvm physical volume from the old raid1

$ pvremove /dev/md0
  Labels on physical volume "/dev/md0" successfully wiped

5) stop (finally) the old array

$ mdadm --stop /dev/md0
mdadm: stopped /dev/md0

And this is where I know I was right from the beginning for doing all this ;)

6) add the last disk to the raid5

$ mdadm --add /dev/md1 /dev/sdd1
mdadm: added /dev/sdd1

And don’t forget to tell mdadm to actually use it (not spare it) =)

$ mdadm --grow /dev/md1 -n3
mdadm: Need to backup 128K of critical section..
mdadm: ... critical section passed.

$ cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid5 sdd1[2] sdc1[1] sdb1[0]
      976759936 blocks super 0.91 level 5, 64k chunk, algorithm 2 [3/3] [UUU]
      [>....................] reshape = 0.1% (1151808/976759936) finish=1356.4min speed=11986K/sec

unused devices: </none><none>

This step takes a loooong time too.

7) grow everything to fit (physical volume, logical volume and filesystem which is reiserfs)
physical volume :

$ pvresize /dev/md1
  Physical volume "/dev/md1" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized
$ pvdisplay
  --- Physical volume ---
  PV Name               /dev/md1
  VG Name               vgdocs
  PV Size               <strong>1,82 TB</strong> / not usable 2,06 MB
  Allocatable           yes
  PE Size (KByte)       4096
  Total PE              <strong>476933</strong>
  Free PE               238467
  Allocated PE          238466
  PV UUID               rDkJvJ-xtnW-dAmQ-TtXR-311H-qayQ-7wxLEE

$ vgdisplay
  --- Volume group ---
  VG Name               vgdocs
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  10
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               <strong>1,82 TB</strong>
  PE Size               4,00 MB
  Total PE              <strong>476933</strong>
  Alloc PE / Size       238466 / 931,51 GB
  Free  PE / Size       238467 / 931,51 GB
  VG UUID               mcE5Hj-Y1Fh-fcsO-AbBu-XIa9-UGoT-LPA6o0

logical volume :

$ lvresize -l 476933 /dev/vgdocs/lvdocs
  Extending logical volume lvdocs to 1,82 TB
  Logical volume lvdocs successfully resized

$ lvdisplay
  --- Logical volume ---
  LV Name                /dev/vgdocs/lvdocs
  VG Name                vgdocs
  LV UUID                Go55Gv-50Rx-XCB1-7Yfx-CYVW-YTyu-duUHFU
  LV Write Access        read/write
  LV Status              available
  # open                 2
  LV Size                1,82 TB
  Current LE             476933
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           252:0

filesystem :

$ df -h /dev/mapper/vgdocs-lvdocs
/dev/mapper/vgdocs-lvdocs
                      932G  758G  175G  82% /media/docs

$ resize_reiserfs  /dev/mapper/vgdocs-lvdocs
resize_reiserfs 3.6.19 (2003 www.namesys.com)

resize_reiserfs: On-line resizing finished successfully.

$ df -h /dev/mapper/vgdocs-lvdocs
/dev/mapper/vgdocs-lvdocs
                      1,9T  758G  1,1T  41% /media/docs

Done ! :)
And everything has been made online on a mounted partition ! :-)

Oh, and I was about to forget! if I want my new array back next time I reboot :

$ mdadm --detail --scan
ARRAY /dev/md1 level=raid5 num-devices=3 metadata=00.90 UUID=3ba98ff9:e832da41:ad30f554:42303922

I have to replace the old line in /etc/mdadm.conf by this one !

# old line : ARRAY /dev/md0 level=raid1 num-devices=2 UUID=b4592a1b:290540de:ad30f554:42303922
# new line : ARRAY /dev/md1 level=raid5 num-devices=3 metadata=00.90 UUID=3ba98ff9:e832da41:ad30f554:42303922

$ cat /etc/mdadm/mdadm.conf
# mdadm.conf
#
# Please refer to mdadm.conf(5) for information about this file.
#

# by default, scan all partitions (/proc/partitions) for MD superblocks.
# alternatively, specify devices to scan, using wildcards if desired.
DEVICE partitions

# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes

# automatically tag new arrays as belonging to the local system
HOMEHOST <system>

# instruct the monitoring daemon where to send mail alerts
MAILADDR root

# definitions of existing MD arrays
# ARRAY /dev/md0 level=raid1 num-devices=2 UUID=b4592a1b:290540de:ad30f554:42303922
ARRAY /dev/md1 level=raid5 num-devices=3 metadata=00.90 UUID=3ba98ff9:e832da41:ad30f554:42303922

For more convenience, I removed the “sudo” in front of most of all the above commands, but of course you have to execute those with root privileges.

Backup-manager

Filed Under (Sysadmin) by Amandine on 23-09-2009

I’m currently trying to find a backup program that fits my need. I found backup-manager, which seems to be easy to install, easy to use, and does what I want : filesystem backup in tarballs, incremential backups, even database backups or svn backups.

On ubuntu, just aptitude it :

sudo aptitude install backup-manager

The config file is here : /etc/backup-manager.conf.
Take the time to fill it correctly, it’s very well explained inside.

If you want different types of backup on the same server, just write several config files, and call backup-manager this way : backup-manager -c /etc/backup-manager-alternate.conf

One last thing : always call it with root privilegies.

Now I’m just wondering how I could easily manage config files and what to backup for all servers… maybe build it dynamically thanks to a database of installed services before sending them on each server.