6,534
edits
Changes
rm translate tags
This document explains how to use user-space <code>ploop</code> utility for typical
use-cases.
{{Warning|The commands below are low-level stuff. It's better to use vzctl which has all the features in place.}}
== Getting help == <!--T:3-->
All user-space ploop management operations are available via "<code>ploop</code>"
utility. Run it w/o args to get help:
Run with a cmd as the only arg to get cmd-specific help, e.g.:
Further ploop commands assume that all necessary modules are loaded:
# modprobe pfmt_ploop1
# modprobe pfmt_raw
# modprobe pio_direct
It's not always required to load both <code>pfmt_ploop1</code> (support of ploop1 format) and
<code>pfmt_raw</code> (support of raw format). If we're going to use ploop1 image file,
plans to snapshot it, <code>pfmt_ploop1</code> can be omitted.
== Initialize image file == <!--T:12-->
In-kernel ploop operates on image files of "<code>raw</code>" or "<code>ploop1</code>" format.
An image file should be created and initialized (entirely in user-space)
before asking in-kernel ploop to start using it.
To just create and initialize a ploop image file with a GPT partition table and an ext4 filesystem inside:
where <code>/ploop.image</code> is full path to new image file and 1g is block-device size
equal to 1GB. This command succeed only if the file <code>/ploop.image</code> didn't
exist at the time of running "<code>ploop init</code>".
== Mount == <!--T:17-->
Assuming that previous steps were done, the following command is used to "mount"
ploop device over image file.
Since this point, <code>/dev/ploopXXXX</code> is operable. One can read/write any data from/to
it (e.g. with "dd"), manipulate partition table on it (with <code>parted</code>, since ploop uses GUID Partition Table, or GPT), format it with <code>mkfs.ext4</code> and mount it on some mount-point. In the other words, since
now <code>/dev/ploop0</code> can be used as any other ordinary block device.
== Snapshot == <!--T:21-->
Let <code>/dev/ploop0</code> be a ploop device running over <code>/ploop.image</code> (i.e. step 5 was
done) and <code>/ploop-delta.image</code> - some full path to non-existent file. Then the
command:
will create empty "ploop1" image file and register it in kernel ploop
forming "snapshotted" configuration <code>top_delta → base_delta</code> where <code>base_delta</code>
is <code>/ploop.image</code> and <code>top_delta</code> is <code>/ploop-delta.image</code>.
Since now, all i/o targeted at <code>/dev/ploop0</code> will change only <code>top_delta</code>.
Actually, while performing snapshot operation in kernel, ploop re-open
for example, to backup <code>base_delta</code>.
It's allowable to snapshot snapshotted configuration. Following example above,
the command:
will form <code>top_delta → delta → base_delta</code> configuration where:
delta := /ploop-delta.image
base_delta := /ploop.image.
All deltas in snapshotted configuration are enumerated in kernel ploop in
the natural order starting from 0 for <code>base_delta</code>:
delta' number is 1
top_delta' number is 2.
This knowledge is useful for online merge below.
== Merge == <!--T:33-->
Merge operation implies copying all new data from an upper delta to a lower
delta. In simplest case of delta2-->delta1 configuration, merge will copy
merge will copy new data from <deltaN, ..., delta2> to delta1.
There are two types of merge: offline and online. "offline" means that we have
a bunch of stand-alone image files w/o kernel ploop running over them.
device or freeze upper-layer apps).
=== Offline merge === <!--T:36-->
ploop has no heruistic about determining raw/ploop1 format of image file. So,
in case of offline merge, user should specify the format of base_delta
explicitly. If it's ploop1, merge command looks like:
This will merge /ploop-delta.image into /ploop.image. More than one source
delta can be specified:
This will merge /ploop-d2.image, /ploop-d1.image and /ploop-d.image into
/ploop.image.
When merge completed, source deltas can be deleted because all data that
was present in them has been copied to destination delta.
For raw format, "-f raw" should be added as option. E.g.:
=== Online merge === <!--T:45-->
In this case user should only specify ploop device and a range of deltas in the
form of LEVEL1..LEVEL2 where LEVEL1 and LEVEL2 should be non-negative integers
deregistered from kernel ploop and can be deleted by user.
Let's consider simple snapshotted configuration as example:
# ploop snapshot -d /dev/ploop0 /ploop-delta.image
# ploop snapshot -d /dev/ploop0 /ploop-delta1.image
In this configuration the command:
will merge /ploop-delta1.image and /ploop-delta.image into /ploop.image. Here
/ploop-delta1.image and /ploop-delta.image are source deltas and can be
deleted.
Alternatively, the command:
will merge /ploop-delta.image into /ploop.image. Here /ploop-delta.image is
source delta and can be deleted.
The last example is:
It will merge /ploop-delta1.image into /ploop-delta.image. Here
/ploop-delta1.image is source delta and can be deleted.
== Migration support == <!--T:58-->
Assuming that /dev/ploop0 is ploop device running over /ploop.image,
/ploop1.image is the path to non-existent file and external_stop is some
executable script or binary, the following command:
will copy /home/ploop.image to /home/ploop1.image iteratively. external_stop
should be an utility that completely freeze all i/o targeted at ploop device.
For instance, container freeze.
From user view, the command above should be equivalent to "external_stop;
cp /home/ploop.image /home/ploop1.image". The benefit of "ploop copy" is
amount of data after external_stop.
It's also possible to split copy operation in two nodes:
node02# ploop copy -s /dev/ploop0 -F external_stop
In this case "ploop copy" on node02 will write data to standard output
in some special binary format and "ploop copy" on node01 will read data
from stndard standard input, parse that special format and store data in
/home/ploop1.image ("-s" stands for "source", "-d" stands for "destination").
This should work if standard output of node02 and standard input of node01
are bound via pipe or socket connection.
== Grow ploop device == <!--T:66-->
and propagate new block-device size to linux kernel (in online case).
=== Offline grow === <!--T:68-->
To grow image file offline, user should specify its format explicitly. The
default is "ploop1" format:
will re-arrange "ploop1" image file /ploop.image to become 32GB size long.
For "raw" format, the command:
will do the same.
=== Online grow === <!--T:75-->
Assuming that /dev/ploop0 is runnung ploop device, the command:
will re-arrange underlying image file, update internal kernel ploop structures
and propagate changes to linux kernel making ploop device 32GB size long.
If user had ext4 formatted and mounted on /dev/ploop0, ext4 fs can be extended
online (when "ploop grow" completed):
== Ballooning == <!--T:81-->
ploop doesn't support pure shrinking block-device size due to lack of online
shrink support in ext4. As a workaround, "ballooning" technique is proposed.
tail of image file.
Desired outcome is image file of smaller size. However, it's quite possible
that inflated balloon file will span only blocks that were never touched
case nothing will be relocated and nothing truncated.
So, if balloon operation succeeded, it's only guaranteed that user of ploop
device won't be able to consume more space than initial block device size
balloon operation will result in significant truncate of image file.
To enable ballooning, ext4 residing on ploop device should be mounted
with special "balloon_ino" option:
where 12 is inode number of balloon file as reported by "ls -i".
(it's assumed that initially, e.g. while constructing container,
someone mounted ext4 on ploop device w/o balloon_ino option, then created
empty balloon file there, found out its inode number and saved it for the
future use).
Currently, only online ballooning is supported. The following command performs
this operation:
where 1g is desired new size of balloon file, /dev/ploop0 is ploop block
device, /mnt_ploop is mount-point where ext4 residing on /dev/ploop0 is
mounted to.
If balloon file was empty, the command above simply inflates it to become
1GB size. If it was non-empty but smaller than 1GB, that command extends it
command does nothing.
Along with "change" sub-command, "ploop balloon" supports a few auxiliary ones:
will show current ploop balloon size.
"grow in progress", "ballooning started", etc. This is useful because on the
one hand balloon operation can't be performed while merge or grow is in
someone before its completion.
previous "ploop balloon" died early leaving in-kernel ploop locked.
will complete previously interrupted balloon operation. An expectation is that
user monitors exit status of ploop commands he/she runs in some way. If
user issued "ploop balloon change" and it was killed in the middle, the user
knows that it didn't complete with zero exit status. Then user shoud should inquirecurrent maintainance maintenance state with "ploop balloon status" command, and, if it
reported "FBLOAD" or "RELOC", the user should use "ploop balloon complete"
before proceeding with any other maintainance maintenance operations (shanphsotsnapshot, merge,
grow, balloon).
will check whether existent balloon file was properly processed. This is useful
if previous "ploop balloon" was interrupted, but "ploop balloon status"
reports "OFF" or "BALLOON" maintainance maintenance state. In this case it's possible
that balloon file was inflated but no further processing happened.
"ploop balloon check" reports total number of free blocks in existent balloon
file. If it's not zero, the user should use the following command to repair
balloon:
This command does essentially the same as "ploop balloon change" but w/o
inflating balloon.
== See also == <!--T:106-->
* [[Ploop]]
* {{Man|ploop|8}}
[[Category: Storage]]