One of main reasons to build own Home Server is to provide NAS functionality. But for this functionality is necessary to create data disk space. This post will show you how to create extendable data storage on the server.
You can have one or more disks for data on the server. Make them available for data can be provided by several ways. The easiest task is to create new partition on the disk, format the partition and mount it somewhere to the filesystem.
But from my experience, after some time the disk starts to be tight for all stored data and will be necessary to extend free space by another disk or by disk replacement to new one with bigger capacity.
With classical mount approach, we will add the new disk, create partition, format it, and mount it. But old and new disks will be separated, then for example if you have folder Video on the old disk and you can store more videos to the server, then you have to create new folder Video2 on new disk, or move some other data from old disk to new one to make space for new items to store them to old Video folder. As you can see, if you have two separated disks then data organization start to be more complicated.
Is more comfortable to have all your videos in one place in Video folder than have two folders named Video and Video2 on two disks, isn’t it?
To solve the problem, Linux offers the solution – LVM (Logical Volume Management). In those days, LVM2 implementation is commonly used.
What is the LVM?
In short, the LVM is an abstraction layer which allows to system administrator to create logical disk volumes and then easily extend, shrink or merge these volumes to fit current disk space requirements. With LVM is possible to join several physical disk partitions to one huge logical partition, split one physical partition to several small logical partitions etc.
Additionally is possible to extend those logical partitions when more space is necessary or shrink them to get free space for other purposes. And what is the best on this approach, many of those operations can be done on the fly and without care about physical disks organization.
On the diagram above you can see an example of two independent LVM Volume groups, which combines 5 physical hard disks to final 5 filesystem units.
The first VOLUME_GROUP_SYS uses two physical partitions (each on different harddisk) to create finally three filesystem units (root FS / /var and /home).
Second VOLUME_GROUP_DATA combines 4 physical partitions to one huge data unit.
Data organization on those logical volume groups is completely hidden to user. From his point of view, he can see only one big volume, as one big hard disk. For the Home Server usage is interesting that is possible to add new hard disk to the server later and join it to existing volume. Then your existing volume grows about the space assigned from new hard disk. Great idea for home server data storage, isn’t it?
When I mentioned cons of the LVM approach, I have to say something about possible risks and disadvantages.
The main problem with LVM can be that if one hard disk joined to the LVM will fail, you can lose complete content of whole LVM units where the disk has been joined. LVM data organization is hidden under LVM abstraction layer, and then can happen that every file in your LVM has some data on HD1 and others on HD2. Then one disk failure can means loss of all data.
Of course disk failure is nightmare case in any computer configuration. If you have really valuable data on those disks, then an additional protection is necessary by regular backup to different media or by RAID technology. The LVM and RAID can work together at glance and it is recommended way for disk failure risk scenarios.
Next disadvantage is possible performance lost in some cases, especially if file is fragmented between two disks. But this is not so important here; we do not need super quick response from our data warehouse.
After the theory part, I’ll try to describe how to create own LVM base data storage with easy extensibility in the future.
At first, detect your disk or partition(s) which will be part(s) of the Logical Volume (LV). We have to modify those disk or partitions to appropriate type.
In my case harddrive reserved for data is presented as /dev/sdb and will be completely used as part of LV which can be extended in the future. Then I created one partition on the sdb and set the partition type to LVM. In console type:
sudo fdisk /dev/sdb
You will get the main menu of the fdisk tool, then use these steps to create appropriate partition:
Press n to create new partition
Press p to create primary partition
Press 1 to assign 1 number
Change type – press t then type 8e (Linux LVM partition type)
Press p to review disk partitions
If you got on review (command p) this result:
Device Boot Start End Blocks Id System
/dev/sdb1 1 182401 1465136001 8e Linux LVM
then you have created correct LVM partition on the second disk. Now write your final partition table to the disk
Press w to write new partition table to the disk
Now is time to install lvm2 subsystem to the Server if is not already installed:
sudo apt-get install lvm2
Now we are prepared to configure LVM on the server. At first, create physical volume:
sudo pvcreate /dev/sdb1
If you can create more physical volumes, simply write paths to these volumes as space separated list to pvcreate command:
sudo pvcreate /dev/sdb1 /dev/sdc1 ….
The physical volume(s) are real hard disk partitions which we can join to the LVM.
When all appropriate physical volumes are created, we have to create the LVM Volume Group (VG) – the virtual unit which will include all physical volumes on bottom side and will offer interface to split this group to logical units.
Before we will start with this task is recommended to calculate the Physical Extend (PE) size value for the LVM Volume Group.
LVM Physical Extend Size
What is the LVM Physical Extend Size value?
In short, this value is smallest block size which the Volume Group can grow or shrank. The Volume Group can be extended or shrank only by multiples of the PE size value and this value cannot be easily changed in future without full data backup and recreation of the Volume Group from scratch.
The PE unit size was essential value for the first LVM implementation because this value defined LVM1 Volume Group maximum size. The one LVM1 Volume Group can contains only 65535 PE units, then maximum LVM1 VG size is 65535*PE size.
The LVM2 implementation hasn’t those limits, but here can be a performance penalty if the VG contains more than 65536 PEs. Documentation says that this penalty is connected only to LVM tools, not to data access, but I think that select proper size for the VG is not bad idea.
If you do not care about that and can use LVM2 in default config, then you can skip next paragraphs. Otherwise here is time you to determine how big data volume you can get now, or in the future. Remember, this value is fixed for LVM and cannot be changed without full data backup, then re-creation LVM again from scratch.
Default PE size value is 4MB. If we use this default value, then LVM1 VG maximum size limit is 65536*4 = 262144 -> it means 256 GB. For LVM2 this value doesn’t limit the VG maximum size but if we extend the VG beyond this value, we can have performance problems in some scenarios.
From previous facts, if we can have the VG size in the future greater then 256MB, then can be better to use higher PE size value. In next table you can find the PE sizes and corresponding LVM1 maximum VG (or recommended LVM2 VG) sizes:
||Maximum LVM1 LV Size
Because the data disk in my server has 1.5 TB size, and I do not expect that I’ll need more then 8TB in the future, I choose 128MB size of the PE unit. It allows to me to grow the LVM VG size up to 8 TB possible data size in the future. Of course, the LV from LVM now can be extended or shrank only by 128MB blocks.
Create LVM Volume Group
With theory from previous paragraphs, we can now create the Volume Group:
sudo vgcreate –s128M data_vg /dev/sdb1
Parameter –s defines the Physical Extend size value, data_vg is name of created Volume Group and /dev/sdb1 identified physical volume connected to this Volume Group. To create the Volume Group from more than one physical volume, extend previous command by list of PV names separated by space:
sudo vgcreate –s128M data_vg /dev/sdb1 /dev/sdc1 ...
Create LVM Logical Volume
Last step to get functional LVM solution is to create one or more Logical Volumes for our purposes. Because I create space for data storage, I have selected to create logical volume data_vg_0 on data_vg Logical Volume and use all available space for that. But is possible to use only small amount of available space from the Volume Group and left rest of that reserved space for future use or repartitioning. All depends on VG usage scenario.
Of course, we cannot create Logical Volume (LV) with greater size than currently available VG size. Then for correct LV creation, we have to get information about available space in the Volume Group. To do this, use the command:
The result will be something like this:
--- Volume group ---
VG Name data_vg
Metadata Areas 1
Metadata Sequence No 2
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 1.36 TB
PE Size 128.00 MB
Total PE 11178
Alloc PE / Size 11142 / 1.36 TB
Free PE / Size 36 / 4.50 GB
VG UUID oPlaik-bfSi-icw7-XmUz-P0e0-wq06-7d6uRM
The line with prefix VG Size defines the Volume Group size, in my case 1.36GB.
Because I can use whole available space for the Logical Volume, I have used this command:
sudo lvcreate –L 1.36TB -ndata_vg0 data_vg
The -L parameter specified the Logical Volume size, and parameter -n specified the name of the Logical Volume inside the Volume Group data_vg what is last parameter of the command; name of VG where the LV is created.
To verify result, you can use the lvdisplay command:
The result of the command looks like this:
--- Logical volume ---
LV Name /dev/data_vg/data_vg0
VG Name data_vg
LV UUID VmkCx9-gPIR-N8C5-Zwx0-ZNov-5GBK-P3F4eK
LV Write Access read/write
LV Status available
# open 1
LV Size 1.36 TB
Current LE 11142
Read ahead sectors auto
- currently set to 256
Block device 252:0
Format and Mount Logical Volume
By previous steps we have created the Logical Volume with 1.36TB size. As I mentioned before, the LVM mechanism causes that Logical Volume(s) looks for rest of the Linux OS as classical partitions. So now the LV is available as other block device under /dev directory. In my case it is available on this path:
The LVM offers second mechanism to access the Logical Volumes, special device /dev/mapper. LVs here are available under special names which are concatenation of the VG name and LV name. In our case:
We can use both paths to access the LVM group. I use the mapper based path
Because LV looks like classical partition, next steps are same as for physical HD partitions. We have to format this LV by filesystem (ext4, ReiserFS, ext2, ext3 etc..) and mount it to our root FS.
I can format the LV by ext4 FS, then I used command:
sudo mkfs.ext4 /dev/mapper/data_vg-data_vg0
Finally I mounted the LV to the root file system. I prefer old way to mount all volumes to /mnt subdirectories. Then I created directory for the LV and mount it:
sudo mkdir /mnt/d0
sudo mount –t ext4 /dev/mapper/data_vg-data_vg0 /mnt/d0
And final check:
sudo df /mnt/d0
If everything is ok, you will see new volume correctly mounted to /mnt/d0.
Filesystem 1K-blocks Used Available Use% Mounted on
1437489508 475949128 888520172 35% /mnt/d0
The data volume is now ready for all file operations. But after reboot the server the volume will be unmounted and unavailable again.
To make mount persistent, we have to modify /etc/fstab file. This file holds all necessary information about all file systems on your server and describes how to mount them during boot process. If you are not familiar with this file, then start to edit the file:
sudo vim /etc/fstab
and add only line bellow to the end of the file:
/dev/mapper/data_vg-data_vg0 /mnt/d0 ext4
noatime,data=writeback,errors=remount-ro 0 1
Note: The content of previous paragraph have to be placed to /etc/fstab as single line !
Save the file and reboot your server. Nov provide previous check for mount point /mnt/d0:
sudo df /mnt/d0
It must show to you correctly mounted LV to this mountpoint:
Filesystem 1K-blocks Used Available Use% Mounted on
1437489508 475949128 888520172 35% /mnt/d0
Now we have allocated and mounted space for our data. In next parts we will take look how to make this space available remotely to store files there.