[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] RFC: virInterface change transaction API

On 04/14/2011 09:03 AM, Dan Kenigsberg wrote:
On Fri, Apr 08, 2011 at 03:31:05PM -0400, Laine Stump wrote:

1) libvirt

    At the libvirt layer, this feature just requires 3 new APIs, which
    are directly passed through to netcf:

        virInterfaceChangeStart(virConnectPtr conn, unsigned int flags);
        virInterfaceChangeCommit(virConnectPtr conn, unsigned int flags);
        virInterfaceChangeRollback(virConnectPtr conn, unsigned int flags);

    For the initial implementation, these will be simple passthroughs
    to similarly named netcf functions. (in the future, it would be
    useful for the server side of libvirt to determine if client<->server
    connectivity was lost due to the network changes, and automatically
    tell netcf to do a rollback).
When such a feature is added, we should make it dependent on FLAG_AUTO_ROLLBACK
passed to ChangeStart. Higher levels on the management stack may want full
controll over when rollback happens.

So are you saying that when they don't add FLAG_AUTO_ROLLBACK that the originals should be available for rollback via virInterfaceChangeRollback(), but that if the system is rebooted, they will be lost? Or do you mean that the originals will still be available for rollback, but the initscript will notice a flag in the save directory and skip the rollback at boot time (leaving the originals there for later manual rollback)? (I think you mean the latter, but want to make sure)

Should there also be a "-f" flag to force saving new originals, even if something is already there? Or is this too dangerous, and we should require the user to call virInterfaceChangeCommit() to erase the old originals?

2) netcf

    The netcf api will have these same three APIs, just named slightly

         ncf_change_start(struct netcf *ncf, unsigned int flags);

            There are two possibilities for this. Either:

             A) call the initscript described below to save all config
                files that might possibly be changed (snapshot_config)


             B) set a flag in *ncf indicating that all future calls
                to netcf that would end up modifying a particular
                config file should save off that file *if it hasn't
                already been saved*.

             (A) is simpler, but relies on the initscript having
             exact/complete matching knowledge of what files netcf may
             change. Should we worry about that and deal with the
             complexities of (B), or is (A) good enough for now?
I'm fine with gradual changes, so (A) is good enough for me, particularly as
long as netcf is shipping the initscripts (3).

Okay. I will use the "copy/erase/restore everything matching a glob" approach for now.

         ncf_change_rollback(struct netcf *ncf, unsigned int flags);

            Again, two possbilities:

               a) save the config of all current interfaces (in memory)
               b) call the initscript below to restore the config to its
                  original state.
               c) compare the new config to the old, and:
                  * bring down any interfaces that no longer exist
                    (PROBLEM: once an interface has no config files, you can
                     no longer operate on it with "ifdown")
                  * bounce any interfaces that have changed
                  * bring up any interfaces that have been re-added

                a) ifdown all interfaces
                b) call initscript to restore previous config
                c) ifup all interfaces.

            (A) is much simpler, but may lead to unnecessary
            difficulties when we bounce interfaces that didn't really
            need it. So, the same question oas for ncf_change_start() -
            is the more exact operation worth the extra complexity?
(A) is simpler? Or did you mean (B)? I'm slightly worried about (B) causing
disconnection of completely unrelated interfaces; this may break concurrent
applications, or even the user of netcf.

Sorry, I meant to swap (A) and (B) before I sent so that I was consistently putting simpler things first and more complicated things later.

It sounds like in addition to saving the files, I need to save a list of interfaces during ncf_change_start; during ncf_change_rollback, I can:

1) get a list of interfaces as they are after the changes about to be rolled back.

2) use a diff of the two lists to ifdown/undefine the interfaces that will be "un-added"

3) use a "uniq -d" of the lists to get a list of all the interfaces that have just been changed (or not touched at all), and save the current XML for all of those interfaces

4) restore the files

5) Get a new list of interfaces, and for each:

    5a) if it's not in the list from (3), ifup the interface
5b) if it is in the list from (3), compare the restored XML to modified ifdown/ifup
          the interface*only* if the two XMLs differ.

Does that sound workable, or will there still be potential for problems (eg, if somebody bridged a host interface, then rolled back, what would happen?)

         ncf_change_commit(struct netcf *ncf, unsigned int flags);

             The simplest function - this will just call the initscript
             to erase the backup (commit_config).

3) initscript

    This initscript will at first live in (be installed by) netcf
    (called /etc/init.d/networking-config?), but hopefully it will
    eventually be accepted by the initscripts package (which includes
    the networking-related initscripts), as it is of general use. (Dan
    Kenigsberg already already took a stab at this script last year,
    but received no reply from the initscripts maintainers, implying
    they may not be too keen on the idea right now - it might take some
    convincing ;-)


    It will have three commands, one of which will be called
    automatically by "start" (the command called automatically at boot


      This will save a copy of (what the script believes are - is this
      problematic?) all network-config related files. It may or may not
      be called by netcf (see the notes in ncf_start_change() above.

      If this function finds that a snapshot has already been taken,
      it should fail.

    rollback_config (automatically called from "start" at boottime)

      This will move back (from the saved copies) all files that were
      changed/removed since snapshot, *and delete any files that have
      been added*.

      Note that this command doesn't need to worry about ifup/ifdown,
      because it will be called prior to any other networking startup
      (part of the reason that netcf will need to deal with that).

      I notice that Dan K's version saves the modified files to a
      "rollback-${date}" directory. Does this seem like a good idea?
      It's nice to not lose anything, but there is no provision for
      eliminating old versions, so it could grow without bound.
I sleep better at night when there are backups... Obviously, I should not have
kept them beyond a certain limit (last 20). And I'd understand if you think that
it is the business of a backup system, or conf management system, to take theses

I'm agnostic. Anyone else have an opinion? Does there need to be a method in the API to get to these backups? Or are they just there for manual intervention in the case of a catastrophe?


      This will just remove all the files in the save directory.

So, the two problems I have right now:

I guess the answers to the following questions are:

1) it's okay to take the easy road.

2) We have to do it the hard way.

1) Do we accept the inexact method of just saving all files that match
    a list of patterns during *start(), then in *rollback() erasing all
    files matching that pattern and copying the old file back? Or do we
    need to keep track of what files have been changed/removed and added,
    and copy back / delete only those files during rollback?

    (A version control system would keep track of this rather nicely,
    but that's too complex for something that's intended to be a
    failsafe (and that we would also like to eventually be in the base
    OS install). Dan B. at one point suggested using patchfiles if I
    wanted the save info to keep exact track of which files would need
    to be replaced/deleted on rollback, but on further thought this
    turns out to not be workable, since we would need to run diff (to
    create the patchfile) after all changes had been made, and any
    outside changes to any of the files would leave the patchfile
    un-appliable, thus causing our "failsafe" to fail :-( ). Therefore,
    we will need to rely on the list of globs to tell us what files
    need to be deleted, or keep our own list in a separate file.)

2) Is it going to be okay to ifdown all interfaces prior to the
    rollback, and ifup all interfaces afterwards? Or must we compare
    the new config to the original, and ifdown only those interfaces
    that had been previously added/changed, then ifup only those
    interfaces that had been previously removed/changed?

3) If anyone has ideas on making the initscript more palatable to the
    initscripts people, please speak up! :-) (one comment from an
    person was that 1) for the general case it would be difficult to
draw the
    line on what parts of network connectivity should be included in this
    rollback functionality, and 2) at some point this becomes a general
    system config problem, and would really be better addressed by a
    general system wide config management system. These are both
    concerns that need well qualified answers. (I tend to think that this
    is intended as a failsafe to prevent unreachable systems, so it should
    be as simple as possible, and thus shouldn't be burdened with the
    complexity of a full system config management system (which could
    also co-exist at a higher level), but better answers are welcome.)

libvir-list mailing list
libvir-list redhat com

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]