Adding Storage to a Linux Server

Some basic tips for adding and working with disks on Linux servers and several examples.

0 . Latest updates and prerequisites.

2023.09.15 – First draft, Ubuntu 22.04 Server.
2024.11.25 – Updated for Ubuntu 24.04 Server.

Check back for updates, if you run into trouble. Leave a comment if the post is missing some detail.

Sudo or root access is needed to manipulate storage devices. Most of this will work with any Linux.

1 . Connecting storage to the server.

SATA, USB, eSATA, SCSI, IDE; directly connected storage. Things like iSCSI are network related, so not covered here. Ensure the storage device has power and is connected. Some USB devices have LEDs to show they are “talking”, some hard disks generate vibrations or a spin “feel” for the motor force to know its working. To be sure, make a note of the model/serial number before closing the computer case.

dmesg or the system logs will be the first place to check if storage is seen. The logs will have much more information than needed, grep will help filter out meaningful lines. For example, a newly connected disk is manufactured by Verbatim:

sudo dmesg | grep Verbatim

Will return all lines with the string “Verbatim”. Beware, this is case-sensitive:

[93537.128269] scsi 6:0:0:0: Direct-Access     Verbatim  Vi550 S3        010D PQ: 0 ANSI: 6

A disk connected via USB will also register as a USB device. This can be found in the dmesg, too, but a better place is lsusb:

sudo lsusb

Will list all USB connected devices:

...
Bus 004 Device 002: ID 152d:0562 JMicron Technology Corp. / JMicron USA Technology Corp. JMS567 SATA 6Gb/s bridge
...

The JMicron SATA bridge is the SATA controller in the USB disk caddy, so the string “Verbatim” will not appear here.

In almost all cases, the disk is seen using the legacy SCSI protocol (regardless whether M2, SSD or SATA), so the disk and partition identifiers are usually sda, sdb, sdc, etc. and a number after that will identify the partition number in order from beginning to end of disk. IDE disks are typically hda, hdb, hdc, etc.

It is possible to grep for disks with just the “sd” part of the device name:

sudo dmesg | grep sd

Will list all line items with that string:

[    0.009783] ACPI: SSDT 0x00000000CD839760 002F08 (v01 SaSsdt SaSsdt   00003000 INTL 20091112)
[    3.893515] sd 0:0:0:0: Attached scsi generic sg0 type 0
[    3.921343] sd 0:0:0:0: [sda] 937703088 512-byte logical blocks: (480 GB/447 GiB)
[    3.948518] sd 0:0:0:0: [sda] 4096-byte physical blocks
[    3.962196] sd 0:0:0:0: [sda] Write Protect is off
[    3.973983] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[    3.974001] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    4.007079]  sda: sda1 sda2
[    4.026696] sd 0:0:0:0: [sda] Attached SCSI disk
[    6.268778] EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
[    6.647630] EXT4-fs (sda2): re-mounted. Opts: (null). Quota mode: none.
[93537.129363] sd 6:0:0:0: Attached scsi generic sg1 type 0
[93537.130320] sd 6:0:0:0: [sdb] 2000409264 512-byte logical blocks: (1.02 TB/954 GiB)
[93537.130528] sd 6:0:0:0: [sdb] Write Protect is off
[93537.130531] sd 6:0:0:0: [sdb] Mode Sense: 67 00 10 08
[93537.130919] sd 6:0:0:0: [sdb] Write cache: enabled, read cache: enabled, supports DPO and FUA
[93537.179051] sd 6:0:0:0: [sdb] Optimal transfer size 33553920 bytes
[93537.183562]  sdb: sdb1 sdb5 sdb6 sdb7 sdb8
[93537.185458] sd 6:0:0:0: [sdb] Attached SCSI disk

The above output shows there are two recognised disks in this server, sda and sdb. sda has just two partitions, sda1 and sda2. sdb has many more, sdb1, sdb5, sdb6, sdb7, sdb8.

Partition numbers are 1-4 for primary partitions and 5 upwards for logical partitions.

Another way to see what is connected is with lsblk. This tool lists all block devices detected:

sudo lsblk

Output looks like this:

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0    7:0    0    62M  1 loop /snap/core20/1587
loop1    7:1    0  63.7M  1 loop /snap/core20/2434
loop2    7:2    0    87M  1 loop /snap/lxd/29351
loop3    7:3    0  89.4M  1 loop /snap/lxd/31333
loop4    7:4    0  38.8M  1 loop /snap/snapd/21759
sda      8:0    0 447.1G  0 disk
├─sda1   8:1    0     1M  0 part
└─sda2   8:2    0 447.1G  0 part /
sdb      8:16   0   7.3T  0 disk
└─sdb1   8:17   0   7.3T  0 part /mnt/temp

2 . Working with partition tables.

Assuming the disk is in good order and connected, fdisk will usually list what partitions it sees:

sudo fdisk -l

The listed partitions found:

Disk /dev/loop0: 61.96 MiB, 64970752 bytes, 126896 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
...
Disk /dev/sda: 447.13 GiB, 480103981056 bytes, 937703088 sectors
Disk model: INTEL SSDSC2BB48
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 34815CF5-FCB8-47C8-8CF9-649F1E3C5D80

Device     Start       End   Sectors   Size Type
/dev/sda1   2048      4095      2048     1M BIOS boot
/dev/sda2   4096 937699327 937695232 447.1G Linux filesystem

Loop devices are in memory block devices or files mounted as block devices. These can be safely ignored. The output above shows the first disk (sda) is an Intel SSD, about 450GB and it has two partitions, sda1 is a boot partition and sda2 is a Linux filesystem.

Assume a new disk has been added to a server and is seen as sdb, fdisk can identify what is there, too:

sudo fdisk -l /dev/sdb

Lists all of sdb:

GPT PMBR size mismatch (2000409230 != 2000409263) will be corrected by write.
Disk /dev/sdb: 953.87 GiB, 1024209543168 bytes, 2000409264 sectors
Disk model:  Vi550 S3
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4096 bytes / 33553920 bytes
Disklabel type: gpt
Disk identifier: A029EFB1-DA5A-444A-914D-9ED6AB147B48

Device         Start        End    Sectors   Size Type
/dev/sdb1         64     204863     204800   100M EFI System
/dev/sdb5     208896    8595455    8386560     4G Microsoft basic data
/dev/sdb6    8597504   16984063    8386560     4G Microsoft basic data
/dev/sdb7   16986112  268435455  251449344 119.9G unknown
/dev/sdb8  268437504 2000409230 1731971727 825.9G VMware VMFS

This disk has an interesting partition table and appears to be a VMware boot disk. Mounting alien partitions is not really in the scope of this post, although it is possible to mount the partition and see or recover the files with the right commands.

In the example below, an 8TB Seagate drive is added to the server.

The drive is connected and can be seen by “fdisk -l”, in this case, the disk is /dev/sdc:

Disk /dev/sdc: 7.28 TiB, 8001563222016 bytes, 15628053168 sectors
Disk model: ST8000VN0022-2EL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: C40A713E-6255-40C7-8500-93A52BF6BEDB

Device     Start         End     Sectors  Size Type
/dev/sdc1     34       32767       32734   16M Microsoft reserved
/dev/sdc2  32768 15627782831 15627750064  7.3T Microsoft basic data

Using fdisk, the disk can be cleaned, then a new partition is created with default settings:

root@server40:~# fdisk /dev/sdc

Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

Command (m for help): n
Partition number (1-128, default 1):
First sector (34-15628053134, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-15628053134, default 15628053134):

Created a new partition 1 of type 'Linux filesystem' and of size 7.3 TiB.
Partition #1 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: y

The signature will be removed by a write command.

Command (m for help): wr
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Notice, in fdisk, hitting “d” deletes a partition. “n” is short for “new” partition and the default is to use all the free space. Nothing is written to the disk until “wr” which is short for “write” which updates the partition table and exits the application.

In some distributions, fdisk is not adequate for disks larger than 4TB. It might be necessary to use cfdisk, a newer tool. cfdisk has a basic text UI, so it might be easier to use for many.

Using cfdisk with sdb:

sudo cfdisk /dev/sdb

The interface is navigated with arrows, [tab], [spacebar] and [enter] keys:

                                 Disk: /dev/sdb
           Size: 953.87 GiB, 1024209543168 bytes, 2000409264 sectors
          Label: gpt, identifier: A029EFB1-DA5A-444A-914D-9ED6AB147B48

    Device           Start         End     Sectors    Size Type
>>  /dev/sdb1           64      204863      204800    100M EFI System
    Free space      204864      208895        4032      2M
    /dev/sdb5       208896     8595455     8386560      4G Microsoft basic data
    Free space     8595456     8597503        2048      1M
    /dev/sdb6      8597504    16984063     8386560      4G Microsoft basic data
    Free space    16984064    16986111        2048      1M
    /dev/sdb7     16986112   268435455   251449344  119.9G unknown
    Free space   268435456   268437503        2048      1M
    /dev/sdb8    268437504  2000409230  1731971727  825.9G VMware VMFS

 lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
 x Partition name: BOOT                                                       x
 x Partition UUID: 3963C570-FFAE-4CC8-B172-D268B648AD13                       x
 x Partition type: EFI System (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)          x
 xFilesystem UUID: 58ED-6D45                                                  x
 x     Filesystem: vfat                                                       x
 mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
[ Delete ]  [ Resize ]  [  Quit  ]  [  Type  ]  [  Help  ]  [  Write ] [  Dump  ]

In the above case, the entire disk is going to be reused, so each partition can be deleted by selecting and deleting each.

The option to create a new partition is only visible when some free space is selected:

                                 Disk: /dev/sdb
           Size: 953.87 GiB, 1024209543168 bytes, 2000409264 sectors
          Label: gpt, identifier: A029EFB1-DA5A-444A-914D-9ED6AB147B48

    Device             Start            End        Sectors       Size Type
>>  Free space          2048     2000409230     2000407183     953.9G



           [   New  ]  [  Quit  ]  [  Help  ]  [  Write ]  [  Dump  ]

The disk will be used with Linux, so the default type is okay. Otherwise it is possible to change the default type. Nothing will be saved unless the changes are written. The idiot proofing requires the word “yes” to be typed out as confirmation.

As a side note, and this post is not about disk recovery, creating a new partition table does not lose all data on the disk. The data is still there, and it can still be recovered.

Check the partition is written as expected with fdisk

sudo fdisk /dev/sdb

The newly created partition is shown:

Disk /dev/sdb: 953.87 GiB, 1024209543168 bytes, 2000409264 sectors
Disk model:  Vi550 S3
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4096 bytes / 33553920 bytes
Disklabel type: gpt
Disk identifier: A029EFB1-DA5A-444A-914D-9ED6AB147B48

Device     Start        End    Sectors   Size Type
/dev/sdb1   2048 2000409230 2000407183 953.9G Linux filesystem

3 . Formatting the partition.

The disk partition cannot be written to logically without a disk format of sorts. In this case the use is for typical data, so ext4, a modern filesystem, understood by almost all Linux distributions, will be used. In this case the partition on /dev/sdc, identified as /dev/sdc1 is being formatted with a tool mkfs. The defaults are accepted here because anything else is outside the scope of this post:

sudo mkfs.ext4 /dev/sdc1

The dialogue for formatting is printed:

mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 1953506385 4k blocks and 244191232 inodes
Filesystem UUID: 1ce6678e-0aca-4c05-a62b-f3cdf295723d
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000, 214990848, 512000000, 550731776, 644972544, 1934917632

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done

By default Ubuntu server supports many format tools:

mkfs         mkfs.cramfs  mkfs.ext4    mkfs.msdos   mkfs.xfs
mkfs.bfs     mkfs.ext2    mkfs.fat     mkfs.ntfs
mkfs.btrfs   mkfs.ext3    mkfs.minix   mkfs.vfat

Unless there is a particular need, go for ext4. It is a stable and reliable filesystem. Of course other types of operating systems may not see the files, for example, if the disk will be shared with Windows’ systems, then mkfs.vfat (FAT32) or mkfs.ntfs is a better choice.

If there is a problem with the device, this usually comes up while using the format tool:

mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 250050897 4k blocks and 62513152 inodes
Filesystem UUID: 7db8a30a-21b7-4c32-aec4-967214280d22
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000, 214990848

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: mkfs.ext4: Input/output error while writing out and closing file system

4 . Mounting the disk.

To mount a disk temporarily at a server, the mount action must be manual. Desktop distributions have tools to auto-mount and auto-umount, for example, if a USB thumb-drive is used. For servers, the assumption is the disk is there to stay.

In either case a location needs to be made that is referred to when accessing the data, in this example the location will be descriptively called “VerbatimSSD”, it can be anything, anywhere, but most system administrators will look to /mnt/ first for a mount point. This is equivalent to drive letters in Windows.

sudo mkdir /mnt/VerbatimSSD

For a temporary use, at the command line, the disk can be mounted:

sudo mount /dev/sdb1 /mnt/VerbatimSSD

The disk mount can be checked with “mount” and “grep”:

sudo mount | grep Verbatim

And dmesg also has relative information if needed:

sudo dmesg | grep sdb1

The details listed:

[120980.484517] EXT4-fs (sdb1): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.

Temporary disks must be unmounted before they are removed, this ensures all cached data is written and the device is no longer in use:

sudo umount /dev/sdb1

It might be the case a server is restarted or a disk is removed and added at a later time. In that case the order of disks determines sda, sdb, sdc, etc. For this reason, it is better to mount disks by a partition serial number called a UUID. For example if the computer is rebuilt and the SATA cables are in a different order, it will not matter because the UUID will not change unless the disk is re-partitioned.

Find the disk UUID with the blkid utility:

sudo blkid | grep sdb

The resulting output contains the UUID:

/dev/sdb1: UUID="3284c7d6-f475-4dea-9a41-9f4803ffd532" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="c1258edc-630b-e84c-9d14-5c76f76d0070"

Almost all Linux distributions use a configuration file to detail the mount actions at boot, /etc/fstab. In this file many settings are established around connections to files, partitions and devices.

Assuming this server will mount the SSD, sdb1, as a temporary file location, /mnt/temp. First step is to create the mount path:

sudo mkdir /mnt/temp

Then mount he location by hand to be sure it actually works:

sudo mount /dev/sdb1 /mnt/temp

Check the location can be written to and read from:

sudo ls / > /mnt/temp/somefile.txt
sudo cat /mnt/temp/somefile.txt

To mount a disk permanently, by its UUID, add a line to the /etc/fstab file:

sudo nano /etc/fstab
/dev/disk/by-uuid/3284c7d6-f475-4dea-9a41-9f4803ffd532 /mnt/temp ext4 defaults 0 1

The defaults are used as this post is about a simple operation. IF required, it is possible to add some mount parameters here to change the characteristics of the mounted media, such as permissions, performance tuning, actions to take in error conditions, etc.

Restart the server to check the mount was permanent and successful. Remember the server will wait a long time for a timeout condition if there is a mount error and this will be displayed at the console. This may happen before sshd is loaded so it will only be possible to see with an attached monitor, at the physical server (or a console view if the server is virtual).

5 . Create a space alert with Discord.

If you followed this post with the setup of discord as an alerting service, create a script that contains these lines and runs periodically:

for i in $(df -h |grep /dev/ | grep -wv tmpfs | awk '{print $6}'); do /opt/discord/discord.sh "$(hostname)" "Space free on $(df -h $i | awk '{print $1,sum=100-$5"%"}' | tail -1)"; done;

This short script lists the free space on each mounted disk.

A summary alert can be created and sent once a week using something like crontab.

This post details how to setup a server monitoring tool, Checkmk.

6 . Supporting this blog.

This type of content takes a lot of effort to write. Each post is drafted, researched, then tested multiple times, even a simple step or detail might take more than a few hours to go from the idea to a published blog post.

Did you notice there are no adverts on this site and the posts are not AI generated?

If you feel I have saved you some time, you can support me by;

©horsefreeglue.com, 2024. Unauthorized use and/or duplication of this material without express and written permission from this site’s author and/or owner is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given.

Spread the love
error: Content is protected !!