[lxc-devel] [RFC 1/1] snapshots in api: define lxcapi_snapshot

Serge Hallyn serge.hallyn at ubuntu.com
Thu Sep 5 18:12:43 UTC 2013


Quoting Stéphane Graber (stgraber at ubuntu.com):
> On Wed, Sep 04, 2013 at 05:14:49PM -0500, Serge Hallyn wrote:
> > Quoting Stéphane Graber (stgraber at ubuntu.com):
> > > On Wed, Sep 04, 2013 at 11:05:02AM -0500, Serge Hallyn wrote:
> > > > Hi,
> > > > 
> > > > before I go on with the snapshots-in-api patchset, I wanted to floar
> > > > this and ask a few questions, as I'm having a hard time deciding how
> > > > we want to talk over the API.
> > > > 
> > > > (Though as I've been typing this out, I think I now see how I want it
> > > > to look.)
> > > > 
> > > > First, the basics:  if you have lxcpath=/var/lib/lxc and take a first
> > > > snapshot of container c1, then the container will be
> > > > /var/lib/lxcsnaps/c1/snap0.  Next snapshot will be /var/lib/lxcsnaps/c1/snap1.
> > > > You can pass a text file containing a commit comment, which will simply be
> > > > stored at /var/lib/lxc/lxcsnaps/c0/snap0/comment, and a timestamp is
> > > > created at /var/lib/lxc/lxcsnaps/c0/snap0/tx.
> > > > 
> > > > To restore that snap1 as container c2, I'm thinking you would
> > > > 
> > > > 	c = lxc_container_new("c0", "/var/lib/lxc");
> > > > 	c2 = c->restore(c, "snap1", "c2");
> > > > 	lxc_container_put(c2);
> > > > 	lxc_container_put(c);
> > > > 
> > > > (Note this doesn't match what's in the patch below).  There are other
> > > > ways it could be done.  For instance we could open the snapshot as
> > > > its own container and call restore on that, i.e.
> > > > 
> > > > 	c = lxc_container_new("snap1", "/var/lib/lxcsnaps/c1");
> > > > 	c2 = c->restore(c, "c2");
> > > > 
> > > > I think I like the first option better though as it keeps callers
> > > > from digging into the storage details.  Thoughts?
> > > > 
> > > > In addition, I'll add lxcapi_snapshot_destroy(), which will look like:
> > > > 
> > > > 	c = lxc_container_new("c0", "/var/lib/lxc");
> > > > 	c->snapshot_destroy(c, "snap1");
> > > > 	lxc_container_put(c);
> > > > 
> > > > As for snapshot_list, I'm thinking it will just look like:
> > > > 
> > > > 	c = lxc_container_new("c0", "/var/lib/lxc");
> > > > 	ns = c->snapshot_entries(c, NULL, 0);
> > > > 	for (i=0; i<ns; i++) {
> > > > 		c2 = c->get_snapshot(c, i);
> > > > 		printf("name is %s, lxcpath %s\n", c->name, c->config_path);
> > > > 		lxc_container_put(c2);
> > > > 	}
> > > > 	lxc_container_put(c);
> > > > 
> > > > with 'timestamp' and 'comment_file' fields being added to struct
> > > > container_struct, usually both NULL.
> > > 
> > > So I think that makes sense and I also prefer the first option you
> > > described. Upon first read of your description it felt a bit weird
> > > having this called restore() since it doesn't actually restore the
> > > snapshot so much as create a new container based on it, but I suppose
> > > that's fine since restore(c, "snpa1", "c0") will probably do what you'd
> > > expect (restore previous state of a container from a snapshot name).
> > 
> > I like the cleaner API if we have restore go back to the original
> > container, but I don't like the added concerns about destroying
> > the original.
> > 
> > I suppose we could have
> > 
> > 	c = lxc_container_new("c0", "/var/lib/lxc");
> > 	c->restore("snap3");
> > 
> > always create a new snapshot of c0, destroy c0, then restore
> > snap3 to c0.  Does that seem like a good behavior?
> > 
> > -serge
> 
> I'd be tempted to say that users should know better and that it
> shouldn't be the API's job to prevent obvious user mistakes.
> 
> I think ->restore("snap3") should wipe the current container and restore
> the snapshot without doing anything fancier than that.
> 
> Then we can have the command line tool ask the user for confirmation and
> have a flag to either snapshot the container first or have the restore
> done against as another container.

Ah but there's another problem.  If you are using overlayfs snapshots
of a dir-based original, then the snapshots become worthless if you
destroy the original.

One way to work around this would be to make sure that you always have
an original elsewhere, and that the thing you're snapshotting is already
anoverlayfs snapshot.  Then all the snapshots would reference the true
original, and we could wipe out the container that was being
snapshotted.

Or, we can make the destination container name optional.  If you're
using btrfs, you can leave the newname null, and lxc will remove
the original container and restore the snapshot to it.  If you're
using overlayfs, then lxc will try to do that but fail on destroying
the original (since it has snapshots), so then you can specify a
new container name.

-serge




More information about the lxc-devel mailing list