Commit graph

133 commits

Author SHA1 Message Date
Vivek Goyal
c115c4aa45 devmapper: Use transaction mechanism during device or snap device creation
Finally this patch uses the notion of transaction for device or snapshot
device creation. 

Following is sequence of event.

- Open a trasaction and save details in a file.
- Create a new device/snapshot device
- If a new device id is used, refresh transaction with new device id details.
- Create device metadata file
- Close transaction.

If docker crashes anywhere in between without closing transaction, then
upon next start, docker will figure out that there was a pending transaction
and it will roll back transaction. That is it will do following.

- Delete Device from pool
- Delete device metadata file
- Remove transaction file to mark no transaction is pending.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
e28a419e11 devmapper: Find a free device Id to use for device creation
Finally, we seem to have all the bits to keep track of all used device
Ids and find a free device Id to use when creating a  new device. Start
using it.

Ideally we should completely move away from retry logic when pool returns
-EEXISTS. For now I have retained that logic and I simply output a warning.
When things are stable, we should be able to get rid of it.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
14d0dd855e devmapper: Open code createDevice() and createSnapDevice()
Open code createDevice() and createSnapDevice() and move all the logic
in the caller.

This is a sheer code reorganization so that all device Id allocation
logic is in one function. That way in case of erros, one can easily
cleanup and mark device Id free again. (Later patches benefit from
it).

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
a44c23fe66 devmapper: Provide a helper function getNextDeviceId()
Right now we are accessing devices.NextDeviceId directly and also 
incrementing it at various places.

Instead provide a helper function which is responsile for
incrementing NextDeviceId and return next deviceId. 

This is just code structuring. This will help later once we
convert this function to find a free device Id and it goes
through a bitmap of used/free device Ids.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
39dc7829de devmapper: Construct initial device Id map from device meta files
When docker starts, build a used/free Device Id map from the per
device meta files we already have. These meta files have the data
which device Ids are in use. Parse these files and mark device as
used in the map.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
4d39e056aa devmapper: Keep track of used device Ids in a bitmap
Currently devicemapper backend does not keep track of used device Ids in
the pool. It tries a device Id and if that device Id exists in pool, it
tries with a different Id and keeps on doing this in a loop till it succeeds.

This worked fine so far but now we are moving to transaction based
device creation and deletion. We will keep deviceId information in 
transaction which will be rolled back if docker crashed before transaction
was complete.

If we store a deviceId in transaction and later figure out it already
existed in pool and docker crashed, then we will rollback and remove
that existing device Id from pool (which we should not have).

That means, we should know free device Id in pool in advance before
we put that device Id in transaction.

Hence this patch creates a bitmap (one bit each for a deviceId), and
sets the bit if device Id is used otherwise resets it. This patch
is just preparing the ground right now. Actual usage will follow
in later patches.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
359a38b26a devmapper: Use a common delete function for all device deletion operation
Right now setupBaseImage() uses deleteDevice() to delete uninitialized
base image while rest of the code uses DeleteDevice(). Change it and
use a common function everywhere for the sake of uniformity.

I can't see what harm can be done by doing little extra locking done
by DeleteDevice().

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
f078bcd8e5 devmapper: Rename NewTransactionId to OpenTransactionId
Very soon we will have the notion of an open transaction and keep its
details in a metafile.

When a new transaction is opened, we allocate a new transaction Id, 
do the device creation/deletion and then we will close the transaction.

I thought that OpenTransactionId better represents the semantics of
transaction Id associated with an open transaction instead of NewtransactionId.

This patch just does the renaming. No functionality change.

I have also introduced a structure "Transaction" which will keep all
the details associated with a transaction. Later patches will add more
fields in this structure.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
7b0a1b814b devmapper: Allocate new transaction Id using current transaction Id
Currently new transaction Id is created using allocateTransactionId()
function. This function takes NewTransactionId and bumps up by one 
to create NewTransactionId.

I think ideally we should be bumping up devices.TransactionId by 1
to come up with NewTransactionId. Because idea is that devices.TransactionId
contains the current pool transaction Id and to come up with a new
transaction Id bump it up by one.

Current code is not wrong as we are keeping NewTransactionId and
TransactionId in sync. But it will be more direct if we look at
devices.TransactionId to come up with NewTransactionId. That way
we don't have to even initialize NewTransactionId during startup
as first time somebody wants to do a transaction, it will be
allocated fresh.

So simplify the code a bit. No functionality change.
 
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
6d347aeb69 devmapper: Remove unnecessary condition check in updatePoolTransactionId()
Currently updatePoolTransactionId() checks if NewTransactionId and
TransactionId are not same only then update the transaction Id in pool. This
check is redundant. Currently we call updatePoolTransactionId() only from
two places and both of these first allocate a new transaction Id.

Also updatePoolTransactionId() should only be called after allocating
new transaction Id otherwise it does not make any sense.

Remove the redundant check and reduce confusion.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
ad9118c696 devmapper: Create new helper function for device and snap creation
Create two new helper functions for device and snap device creation. These
functions will not only create the device and also register the device.

Again, makes the code structure better and keeps all transaction logic
contained to functions instead of spilling over into functions like
setupBaseImage or AddDevice().

Just the code reorganization. No functionality change.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
442247927b devmapper: Provide a function unregisterDevice()
Currently registerDevice() adds a device to in-memory table, saves metadata
and also updates the pool transaction ID.

Now move transaciton Id update out of registerDevice() and provide a new
function unregisterDevice() which does the reverse of registerDevice().
This will simplify some code down the line and make it more structured.

This is just code reorganization and should not change functionality.
 
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
7b2b15d3e9 devmapper: Use device id as specified by caller
Currently devicemapper CreateDevice and CreateSnapDevice keep on retrying
device creation till a suitable device id is found. 

With new transaction mechanism we need to store device id in transaction
before it has been created.

So change the logic in such a way that caller decides the devices Id to
use. If that device Id is not available, caller bumps up the device Id
and retries.

That way caller can update transaciton too when it tries a new Id. Transaction
related patches will come later in the series.
  
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
5be77901cd devmapper: Do not add back device into hash map if meta file removal failed
When we are deleting a device, we also delete associated metadata file. If
that file removal fails, we are adding back the device in in-memory
table. I really can't see what's the point. When next lookup takes place
it will be automatically loaded if need be. Remove that code.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
824a87f7ef devmapper: Move pool id query and migration of old data in separate function
Right now initMetaData() first queries the pool for current transaciton Id
and then it migrates the old metafile.

Move pool transaction Id query and file migration in separate functions
for better code reuse and organization.

Given we have removed device transaction Id dependency from saveMetaData(),
we don't have to query pool transaction Id before migrating files.
 
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
0db6cc85ed devmapper: Remove transaction Id update from saveMetaData()
Right now saveMetaData() is kind of little overloaded function. It is
supposed to save file metadata to disk. But in addition if user has
bumped up NewTransactionId before calling saveMetaData(), then it will
also update the transaction ID in pool.

Keep saveMetaData() simple and let it just save the file. Any update
of pool transaction ID is done inline in the code which needs it.

Also create an helper function updatePoolTransactionId() to update pool
transaction Id.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
004d8b9b33 devmapper: Remove unnecessary call to allocateTransactionId() during device removal
Remove call to allocateTransactionId() during device removal. This seems to
be unnecessary and it is not clear what this call is doing.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
b721d6d8d0 devmapper: Do not check for transaction id during device metadata loading
Again, just because device transaction id is greater than pool transaction
id, it does not guarantee that device is in the pool. So do not check
of this during loading of device metadata.

Docker needs to deal with it. And device activation will fail when we try
to activate a device for whom metafile is present but there is no device
in the pool.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vivek Goyal
bb00453e58 devmapper: Do not check for pool transaction id during old metadata migration
Current code is associating a transaction id with each device and if pool
transaction id is greater that value, then current code assumes that device
is there in pool.

Transaction id of pool is a mechanism so that during device creation and
removal one can define a transaction and during startup figure out if
transaction was complete or not. I think we are using transaction id 
throughout the code little inappropriately.

For example, if a device is being deleted, it is possible that we deleted
the device from pool but before we could delete metafile docker crashed.
When docker comes back it will think that device is in the pool (due to
device transaction id being less than pool transaction id) but device
is not in the pool.

Similary, it could happen that some data in the pool is corrupted and
during pool repair some devices are lost (without docker knowing about
it). In that case tool pool transaction id will be higher than device
transaction id and there are no guaratees that device is actually in
the pool.

So move away from this model where we think that a device is in pool if pool
transaction id is greater than device transaction Id. Per device
transaction Id just says that after device creation this should be pool's
transaction Id and nothing more.

Transaction id is per pool property (as opposed to per device property) and
will be used internally to figure out if last transaction was complete or
not and recover from failure during docker startup.  

If for some reason metafile is present but device is not in pool, then 
device activation will fail later.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-12-03 13:06:43 -05:00
Vincent Batts
b47ff77b5c Merge pull request #9006 from snitm/thin-pool-improvements
Thin pool improvements
2014-11-26 14:44:09 -05:00
Mike Snitzer
b9f1b0a751 devmapper: cleanup some extraneous branching in setupBaseImage()
Docker-DCO-1.1-Signed-off-by: Mike Snitzer <snitzer@redhat.com> (github: snitm)
2014-11-24 20:06:41 -05:00
unclejack
209deff963 don't call reexec.Init from chrootarchive
Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)

Conflicts:
	daemon/graphdriver/aufs/aufs_test.go
		fixed conflict caused by imports
2014-11-25 01:03:40 +02:00
unclejack
1cb17f03d0 add pkg/chrootarchive and use it on the daemon
Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)

Conflicts:
	builder/internals.go
	daemon/graphdriver/aufs/aufs.go
	daemon/volumes.go
		fixed conflicts in imports
2014-11-25 01:03:40 +02:00
Jessie Frazelle
c59b308b6b Merge pull request #9223 from vbatts/vbatts-overlay_notfound
overlayfs: more helpful output when not supported
2014-11-21 19:58:01 -08:00
Mike Snitzer
553b50bd37 devmapper: remove unnecessary else branch in getPoolName()
Docker-DCO-1.1-Signed-off-by: Mike Snitzer <snitzer@redhat.com> (github: snitm)
2014-11-21 21:36:23 -05:00
Michael Crosby
f8509e7940 Mknod more loopbacks for devmapper
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
2014-11-21 16:20:35 -08:00
unclejack
4180579313 graphdriver/aufs: fix tmp cleanup in tests
Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)
2014-11-21 18:31:45 +02:00
Tonis Tiigi
6705477673 Fix misuses of format based logging functions
Signed-off-by: Tõnis Tiigi <tonistiigi@gmail.com> (github: tonistiigi)
2014-11-19 23:59:02 +02:00
Vincent Batts
3287ca1e45 overlayfs: more helpful output when not supported
based on https://github.com/docker/docker/pull/7619#discussion_r20385086

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2014-11-18 22:53:04 -05:00
Ahmet Alp Balkan
b64c9b521a Extract TreeSize to daemon build
TreeSize uses syscall.Stat_t which is not available on Windows.
It's called only on daemon path, therefore extracting it to daemon
with build tag 'daemon'

Signed-off-by: Ahmet Alp Balkan <ahmetb@microsoft.com>
2014-11-14 18:20:53 -08:00
Michael Crosby
8682bac309 Merge pull request #9151 from tonistiigi/aufs-clipping-fix
Fix AUFS silent mount errors on many layers
2014-11-14 17:35:07 -08:00
Michael Crosby
25643f8932 Merge pull request #9172 from vbatts/vbatts-dm_maintainer
pkg/devicemapper: missed MAINTAINERS on split
2014-11-14 13:29:34 -08:00
unclejack
916a10dd91 Merge pull request #7619 from alexlarsson/overlayfs
Add overlayfs graph backend
2014-11-14 22:59:59 +02:00
Vincent Batts
3ec623ee2f pkg/devicemapper: missed MAINTAINERS on split
Signed-off-by: Vincent Batts <vbatts@redhat.com>
2014-11-14 11:12:23 -05:00
Jessie Frazelle
870a695375 Merge pull request #9011 from vbatts/vbatts-btrfs_information
btrfs: information for the information gods
2014-11-13 20:47:07 -08:00
Vincent Batts
25154682a5 btrfs: build tag to enable showing version info
be default it is on, with build tags to disable the version info

Signed-off-by: Vincent Batts <vbatts@redhat.com>
2014-11-13 16:43:53 -05:00
Mike Snitzer
e49567ba72 devmapper: disable discards by default if dm.thinpooldev was specified
User may still enable discards by setting dm.blkdiscard=true

Docker-DCO-1.1-Signed-off-by: Mike Snitzer <snitzer@redhat.com> (github: snitm)
2014-11-13 13:37:47 -05:00
Tonis Tiigi
6d97339ca2 Fix AUFS silent mount errors on many layers
Fixes #1171
Fixes #6465

Data passed to mount(2) is clipped to PAGE_SIZE if its bigger. Previous 
implementation checked if error was returned and then started to append layers 
one by one. But if the PAGE_SIZE clipping appeared in between the paths, in the 
permission sections or in xino definition the call would not error and 
remaining layers would just be skipped(or some other unknown situation).

This also optimizes system calls as it tries to mount as much as possible with 
the first mount.


Signed-off-by: Tõnis Tiigi <tonistiigi@gmail.com> (github: tonistiigi)
2014-11-13 20:13:13 +02:00
Mike Snitzer
2b10749cdd devmapper: Add option for specifying an lvm2 created thin-pool device
Ideally lvm2 would be used to create/manage the thin-pool volume that is
then handed to docker to exclusively create/manage the thin and thin
snapshot volumes needed for it's containers.  Managing the thin-pool
outside of docker makes for the most feature-rich method of having
docker utilize device mapper thin provisioning as the backing storage
for docker's containers.  lvm2-based thin-pool management feature
highlights include: automatic or interactive thin-pool resize support,
dynamically change thin-pool features, automatic thinp metadata checking
when lvm2 activates the thin-pool, etc.

Docker will not activate/deactivate the specified thin-pool device but
it will exclusively manage/create thin and thin snapshot volumes in it.

Docker will not take ownership of the specified thin-pool device unless
it has 0 data blocks used and a transaction id of 0.  This should help
guard against using a thin-pool that is already in use.

Also fix typos in setupBaseImage() relative to the thin volume type of
the base image.

Docker-DCO-1.1-Signed-off-by: Mike Snitzer <snitzer@redhat.com> (github: snitm)
2014-11-12 21:03:04 -05:00
Vincent Batts
42861f3b45 Merge pull request #8986 from vbatts/vbatts-pkg_devicemapper_bindings
devicemapper: split out devicemapper bindings
2014-11-12 19:59:36 -05:00
Michael Crosby
9670871e01 Merge pull request #8982 from rhvgoyal/save-restore-device-id
Save restore device Id: issue #8978
2014-11-12 15:41:27 -08:00
Vivek Goyal
15c74bebc1 devmapper: Take care of some review comments
Took care of some review comments from crosbymichael.

v2:
- Return "err = nil" if file deviceset-metadata file does not exist.
- Use json.Decoder() interface for loading deviceset metadata.

v3:
- Reverted back to json marshal interface in loadDeviceSetMetaData().

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-11-12 09:36:32 -05:00
Vincent Batts
318b11f62f btrfs: information for the information gods
Signed-off-by: Vincent Batts <vbatts@redhat.com>
2014-11-06 16:17:10 -05:00
Vivek Goyal
0f57c90245 docker-remove-redundant-json-tags
In previous patch I had introduce json:"-" tags to be on safer side to make
sure certain fields are not marshalled/unmarshalled. But struct fields
starting with small letter are not exported so they will not be marshalled
anyway. So remove json:"-" tags from there.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-11-06 15:59:25 -05:00
Vincent Batts
2fbfa29318 devmapper: add vbatts to MAINTAINERS
Signed-off-by: Vincent Batts <vbatts@redhat.com>
2014-11-06 14:06:52 -05:00
Vincent Batts
e2f8fbfbcc devicemapper: split out devicemapper bindings
This is a first pass at splitting out devicemapper into separate, usable
bindings.

Signed-off-by: Vincent Batts <vbatts@redhat.com>
2014-11-05 18:10:38 -05:00
Vivek Goyal
ff56531de4 devmapper: Fix gofmt related build failures
My pull request failed the build due to gofmat issues. I have run gofmt
on specified files and this commit fixes it.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-11-05 14:39:54 -05:00
Vivek Goyal
8c9e5e5e05 devmapper: Save and restore NextDeviceId in a file
The way thin-pool right now is designed, user space is supposed to keep
track of what device ids have already been used. If user space tries to
create a new thin/snap device and device id has already been used, thin
pool retuns -EEXIST.

Upon receiving -EEXIST, current docker implementation simply tries the
NextDeviceId++ and keeps on doing this till it finds a free device id.

This approach has two issues.

- It is little suboptimal.
- If device id already exists, current kenrel implementation spits out
  a messsage on console.

[17991.140135] device-mapper: thin: Creation of new snapshot 33 of device 3 failed.

Here kenrel is trying to tell user that device id 33 has already been used.
And this shows up for every device id docker tries till it reaches a point
where device ids are not used. So if there are thousands of container and
one is trying to create a new container after fresh docker start, expect
thousands of such warnings to flood console.

This patch saves the NextDeviceId in a file in
/var/lib/docker/devmapper/metadata/deviceset-metadata and reads it back
when docker starts. This way we don't retry lots of device ids which 
have already been used. 

There might be some device ids which are free but we will get back to them
once device numbers wrap around (24bit limit on device ids).

This patch should cut down on number of kernel warnings.

Notice that I am creating a deviceset metadata file which is a global file
for this pool. So down the line if we need to save more data we should be
able to do that.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-11-05 09:25:02 -05:00
Vivek Goyal
8e9a18039b devmapper: Export nextDeviceId so that json.Marshal() can operate on it
I was trying to save nextDeviceId to a file but it would not work and
json.Marshal() will do nothing. Then some search showed that I need to
make first letter of struct field capital, exporting this field and
now json.Marshal() works.

This is a preparatory patch for the next one.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-11-05 09:25:02 -05:00
Vivek Goyal
67fbd34d83 devmapper: Move file write and rename functionality in a separate function
Currently we save device metadata and have a helper function saveMetadata()
which converts data in json format as well as saves it to file. For
converting data in json format, one needs to know what is being saved.

Break this function down in two functions. One function only has file
write capability and takes in argument about byte array of json data.
Now this function does not have to know what data is being saved. It
only knows about a stream of json data is being saved to a file.

This allows me to reuse this function to save a different type of
metadata. In this case I am planning to save NextDeviceId so that
docker can use this device Id upon next restart. Otherwise docker
starts from 0 which is suboptimal.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2014-11-05 09:25:02 -05:00