Resize an iscsi LUN in Linux

How To Resize an iscsi LUN in Linux

NetApp storage systems also allow you to resize a LUN dynamically; however, the iSCSI layer in Linux is not capable of detecting the change in the LUN size. To display the new size of the LUN you must restart the iSCSI service. But a restart of the iSCSI service fails if any iSCSI devices are mounted at that time. Because of this, even if the LUN on which the file system is located is resized, you must unmount the file system and then restart iSCSI and the multipathing service before Linux can detect the new size.

!!! warning
Though this procedure below has been tested, it is always a good idea to back up your data before attempting resizing.

Collect information on the partition to be resized

For the purposes of this example, /dev/sdc1 is the iscsi lun partition to be resized. Run through the following commands and set the information aside:

~# df /dev/sdc1
~# df -h /dev/sdc1
~# fdisk -l /dev/sdc
~# fdisk -s /dev/sdc1

!!! info
The first two commands are to provide a “snapshot” look at the size of the partition before making any changes. The third command contains useful information needed to successfully increase the partition in a later step. Make note of the starting cylinder from the output. For example:

PRODUCTION linux01 # fdisk -l /dev/sdc

Disk /dev/sdc: 32.2 GB, 32212254720 bytes
64 heads, 32 sectors/track, 30720 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes

Device Boot Start End Blocks Id System
/dev/sdc1 1 30720 31457264 83 Linux

!!! tip
Note the amount of cylinders and what the starting cylinder is. In the example above, the starting cylinder is 1.

!!! info
If the partition to be increased contains system/OS files, you may need to boot off a rescue disk to perform the resize operation. Otherwise, it the parition is a data partition, then it simply needs to be unmounted.

Increase size of the LUN on the NetApp

netapp> lun resize /vol/mylun +5g

Unmount the device

PRODUCTION linux01 # umount /dev/sdc1

Perform a file system check

PRODUCTION linux01 # fsck -n /dev/sdc1

Restart iscsi daemon

PRODUCTION linux01 # /etc/init.d/iscsid restart
* Unmounting iscsi partition... ...
* Logging out of iSCSI targets
* Logging out of session [sid: 1, target: iqn.1992-08.com.netapp:sn.151753609, portal: 10.10.2.2,3260]
* Logout of [sid: 1, target: iqn.1992-08.com.netapp:sn.151753609, portal: 10.10.2.2,3260]: successful
* Stopping iSCSI initiator service ... [ ok ]
* Removing iSCSI modules ... [ ok ]
* Loading iSCSI modules ... [ ok ]
* Starting iSCSI initiator service ... [ ok ]
* Logging into iSCSI targets
* Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.151753609, portal: 10.10.2.2,3260]
* Login to [iface: default, target: iqn.1992-08.com.netapp:sn.151753609, portal: 10.10.2.2,3260]: successful
* Waiting for udev to process new devices
* Mounting iscsi partition... ...

!!! note
From the ‘fdisk -l’ output below, the device changed from /dev/sdc to /dev/sdb. This may happen due to udev during iscsi restart and is normal. You will also notice the amount of cylinders has changed due to the lun size increase command performed on the netapp but the cylidner start/end is the same as before.

PRODUCTION linux01 # fdisk -l
<snip>

Disk /dev/sdb: 107.3 GB, 107374182400 bytes
64 heads, 32 sectors/track, 102400 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes

Device Boot Start End Blocks Id System
/dev/sdb1 1 30720 31457264 83 Linux

Run a file system check

Ensure the file system is clean before attempting to change the layout of the partition.

PRODUCTION linux01 # fsck -n /dev/sdb1
fsck 1.38 (30-Jun-2005)
e2fsck 1.38 (30-Jun-2005)
/dev/sdb1 has gone 701 days without being checked, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
/lost+found not found. Create? no

Pass 4: Checking reference counts
Pass 5: Checking group summary information

/dev/sdb1: ********** WARNING: Filesystem still has errors **********

/dev/sdb1: 16940/3932160 files (0.3% non-contiguous), 7425413/7864316 blocks

It still has errors because lost+found directory is missing in ==MY== example, but I opted not to create it in this step to avoid further changes to the file system.

(optional) Convert the file system into an ext2 file system

This may be optional. Depending on your kernel, resize2fs may only work on ext2 file systems. Refer to your man page. In my case, it doesn’t support ext3 so the steps involved are to:

  1. remove the journal

    PRODUCTION linux01 # tune2fs -O ^has_journal /dev/sdb1
    tune2fs 1.38 (30-Jun-2005)
  2. delete the current partition table and recreate it with the new cylinder boundaries

    PRODUCTION linux01 # fdisk /dev/sdb

    The number of cylinders for this disk is set to 102400.
    There is nothing wrong with that, but this is larger than 1024,
    and could in certain setups cause problems with:
    1) software that runs at boot time (e.g., old versions of LILO)
    2) booting and partitioning software from other OSs
    (e.g., DOS FDISK, OS/2 FDISK)

    Command (m for help): p

    Disk /dev/sdb: 107.3 GB, 107374182400 bytes
    64 heads, 32 sectors/track, 102400 cylinders
    Units = cylinders of 2048 * 512 = 1048576 bytes

    Device Boot Start End Blocks Id System
    /dev/sdb1 1 30720 31457264 83 Linux

    Command (m for help): d
    Selected partition 1

    Command (m for help): p

    Disk /dev/sdb: 107.3 GB, 107374182400 bytes
    64 heads, 32 sectors/track, 102400 cylinders
    Units = cylinders of 2048 * 512 = 1048576 bytes

    Device Boot Start End Blocks Id System

    Command (m for help): n
    Command action
    e extended
    p primary partition (1-4)
    p
    Partition number (1-4): 1
    First cylinder (1-102400, default 1): 1 <- taken from fdisk -l output in preliminary steps. Make sure start cylinder is same as it was before!!! If you get an error like "Value out of range", you may need to use parted instead of fdisk. Se footnotes below.
    Last cylinder or +size or +sizeM or +sizeK (1-102400, default 102400):
    Using default value 102400

    Command (m for help): p

    Disk /dev/sdb: 107.3 GB, 107374182400 bytes
    64 heads, 32 sectors/track, 102400 cylinders
    Units = cylinders of 2048 * 512 = 1048576 bytes

    Device Boot Start End Blocks Id System
    /dev/sdb1 1 102400 104857584 83 Linux

    Command (m for help): w
    The partition table has been altered!

    Calling ioctl() to re-read partition table.
    Syncing disks.
  1. Run another file system check. Note this time we use e2fsck because we’re still an ext2 file system. This time, I created the lost+found.

    PRODUCTION linux01 # e2fsck -f /dev/sdb1
    e2fsck 1.38 (30-Jun-2005)
    Pass 1: Checking inodes, blocks, and sizes
    Pass 2: Checking directory structure
    Pass 3: Checking directory connectivity
    /lost+found not found. Create<y>? yes

    Pass 4: Checking reference counts
    Pass 5: Checking group summary information

    /dev/sdb1: ***** FILE SYSTEM WAS MODIFIED *****
    /dev/sdb1: 16941/3932160 files (0.3% non-contiguous), 7392612/7864316 blocks

Resize the partition

PRODUCTION linux01 # resize2fs /dev/sdb1
resize2fs 1.38 (30-Jun-2005)
Resizing the filesystem on /dev/sdb1 to 26214396 (4k) blocks.
The filesystem on /dev/sdb1 is now 26214396 blocks long.

Run another fsck

Ensure it is clean by running another file system check:

PRODUCTION linux01 # fsck -n /dev/sdb1
fsck 1.38 (30-Jun-2005)
e2fsck 1.38 (30-Jun-2005)
/dev/sdb1: clean, 16941/13107200 files, 7680539/26214396 blocks

The resize operation is now complete.

Add an ext3 journal to the filesystem

PRODUCTION linux01 # tune2fs -j /dev/sdb1
tune2fs 1.38 (30-Jun-2005)
Creating journal inode: done
This filesystem will be automatically checked every 25 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

Remount the lun

PRODUCTION linux01 # mount /dev/sdb1  /mnt

Enjoy the new size!

PRODUCTION linux01 # df -h /dev/sdb1
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 99G 28G 67G 30% /var/services/db/mysql
PRODUCTION linux01 #
PRODUCTION linux01 # ls -l /mnt
total 28853216
drwx------ 2 mysql mysql 4096 Jul 30 22:47 database22_100
drwx------ 2 mysql mysql 4096 Jul 30 22:47 database22_101
drwx------ 2 mysql users 4096 Jul 30 22:47 database22_102
drwx------ 2 mysql users 4096 Jul 30 22:47 database22_103
drwx------ 2 mysql users 4096 Jul 30 22:47 database22_104
drwx------ 2 mysql users 4096 Jul 30 22:47 database22_105
drwx------ 2 mysql users 4096 Jul 30 22:47 database22_106
drwx------ 2 mysql users 4096 Jul 30 22:47 database22_107
...
...

Footnotes

In this example, fdisk supplied an error “Value out of range” when trying to set a starting cyclinger to a value less than 2048. I had an incident where a LUNs starting cyclinder was 63, and since I did not want to lose the data held between data 63 and 2048, I used parted to repartition the disk. Having a starting cyclinder of 63 more than likely means not be aligned with the underlying storage, but that’s another topic. There may be better ways to do this, but this is how I’ve worked it out and am documenting it until I have the opportunity to run through the process again. If improvements can be made, I’ll update the doc or will review anyone who cares to comment.

PRODUCTION linux101 ~ # parted /dev/sdb
GNU Parted 3.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: NETAPP LUN (scsi)
Disk /dev/sdb: 107GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 107GB 107GB primary
(parted) unit cyl
(parted) print
Model: NETAPP LUN (scsi)
Disk /dev/sdb: 13055cyl
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 13055,255,63. Each cylinder is 8225kB.
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 0cyl 13054cyl 13054cyl primary
(parted) unit s (you might have to type 'unit <enter> s')
(parted) print
Model: NETAPP LUN (scsi)
Disk /dev/sdb: 209743872s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 2048s 209717247s 209715200s primary
(parted) rm 1
(parted) print
Model: NETAPP LUN (scsi)
Disk /dev/sdb: 209743872s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
(parted) mkpart
Partition type? primary/extended? primary
File system type? [ext2]? ext3
Start? 63s
End? 209717247s <<< use value from output in print above in matching highlight (see footnote below)
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel? Ignore
(parted) print
Model: NETAPP LUN (scsi)
Disk /dev/sdb: 209743872s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 63s 209717247s 209717185s primary ext2
(parted) quit
Information: You may need to update /etc/fstab.

PRODUCTION atl4mysqlv101 ~ # fdisk -l
Disk /dev/sda: 292.3 GB, 292326211584 bytes
255 heads, 63 sectors/track, 35539 cylinders, total 570949632 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 identifier: 0x77e3ed41
Device Boot Start End Blocks Id System
/dev/sda1 63 8016434 4008186 83 Linux
/dev/sda2 8016435 16032869 4008217+ 83 Linux
/dev/sda3 16032870 20049119 2008125 82 Linux swap / Solaris
/dev/sda4 20049120 570934034 275442457+ 5 Extended
/dev/sda5 20049183 36065924 8008371 83 Linux
/dev/sda6 36065988 52082729 8008371 83 Linux
/dev/sda7 52082793 570934034 259425621 83 Linux
Disk /dev/sdb: 107.4 GB, 107388862464 bytes
255 heads, 63 sectors/track, 13055 cylinders, total 209743872 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 identifier: 0x0005ed03
Device Boot Start End Blocks Id System
/dev/sdb1 63 209717247 104858592+ 83 Linux
PRODUCTION mysqlv101 ~ #

Footnotes:

If the end sector matches what it was previous, I’ve had to use fdisk just to see what the End value is of the extended LUN, then use parted to ensure the use of the correct starting cyl.

Share