User space part of online resizing and moving is implemented in src/libsurprise/convert_online.c
.
It consists of two parts:
Detection of online support is done through function check_online()
. If online
support is not compiled to Surprise project it will just return that online functions are
not available. If online functions are compiled we have to check whether current kernel supports
them. This is done by scanning /proc/ksyms
file. In kernel code we export two functions
-- move_partition()
and ext2_resize()
so they get to
/proc/ksyms
file and we can easily detect them. We export those two functions because
partition moving and ext2 resizing can be configured separately.
I know this way on detecting has a few unpleasant features. At first it's abusing of system
of symbol exporting. Secondly /proc/ksyms
exists only if module support is compiled
into the kernel and so this way of detecting needn't work on all systems. The second problem is
just pure consequence of the first one.
The problem is I don't know any good way how to deal with detecting. Problem with ioctls
is that we need at least some block device to call ioctl on and where we should get it? It
needn't exist at all and even if it exists how we can find it? The second way might
be to create or use some /proc
file. For example /proc/misc
seems
to be a candidate. But I don't find this way good too (but maybe it's better than abusing
symbol exporting).
Userspace wrapper is implemented in function convert_online()
. This function
gets source partition description(imported
), destination partition description
(exported
) and path to filesystem root on given partition (directory
) --
NULL
if there's not any mounted filesystem. It first
checks whether error system was initialized and if not it will initialize it. Then it
checks whether supplied arguments are reasonable (like if there aren't NULL
s
where should be some structures, if mounted filesystem is ext2 etc.). When all checks
are done we start moving and resizing. If destination partition is smaller then the source
one we shrink the filesystem first (we call mount(2)
with proper parameters) and
then we shrink the partition (we just call ioctl(2)
). If the destination partition
has other position than the source one we move the partition to new location.
Then if the destination partition is larger than the source one we enlarge the
partition and the filesystem. See
moving interface and
ext2 resizing interface for description of both kernel
interfaces.
If any error during converting occurs we try to return partitions to the state they were at the beginning (e.g. we grow the partition and filesystem back when moving failed).