[libvirt] RFC backup API

Maxim Nestratov mnestratov at virtuozzo.com
Thu Apr 28 14:02:20 UTC 2016


27.04.2016 15:31, Daniel P. Berrange пишет:

> On Fri, Apr 08, 2016 at 11:47:29PM +0300, Maxim Nestratov wrote:
>> Hello all,
>>
>> Here is the first more detailed view on the list of the backup API functions
>> that
>> look reasonable to have. Though they are presented with parameters and short
>> description all these are the subject to discuss and I kindly ask you to
>> take a
>> look and comment. Your ideas and considerations are very welcome.
>>
>>
>> --------------------------------------------------------------------------------
>> virBackupPtr virDomainBackupCreateXML(virDomainPtr domain,
>>                                        const char * xmlDesc,
>>                                        unsigned int flags)
> Nitpick, lets call it virDomainBackupPtr rather than just virBackupPtr.
> Likewise use virDomainBackup as name prefix for other data types
> and method names

Ok

>>   Create a new backup of a domain based on the backup xml contained in
>> xmlDesc.
>>
>>     - domain: a domain object
>>     - xmlDesc: string containing an XML description of the backup
>>     - flags: bitwise-OR of virBackupCreateFlags
>>     - returns: an opaque virBackupPtr on success or NULL on failure
>>
>>    enum virBackupCreateFlags {
>>
>>      to be defined
>>    }
>>
>>
>>   An example of backup xml:
>>
>>      <domainbackup>
>>        <uuid>54c70d40-26bb-48cd-9639-b3a1e9adf650</uuid>
>>        <description>Any string</description>
>>        <parent>
>> <uuid>d2ee2566-bef2-408f-ac7a-eb8004186074</uuid>
>>        <parent>
>>        <disks>
>>          <disk name='vda'>
>>              <target>
>>              ... volume, file, or any possible target
>>              </target>
>>          </disk>
>>          <disk name='vdb'>
>>              <target>
>>              ...
>>              </target>
>>          </disk>
>>        </disks>
>>      </domainbackup>
>>
>> --------------------------------------------------------------------------------
>> virBackupPtr virBackupStartUnmanaged(virDomainPtr domain,
>>                                       const char * xmlDesc,
>>                                       unsigned int flags)
>>
>>   Start a new unmanaged backup of a domain based on the backup xml contained
>> in
>>   xmlDesc. This function starts 'blockdev-backup' QMP command to block
>> devices
>>   exposed as nbd servers by qemu. It is for 3d party managed backups.
>>
>>     - domain: a domain object
>>     - xmlDesc: string containing an XML description of the backup
>>     - flags: bitwise-OR of virBackupCreateFlags
>>     - returns: an opaque virBackupPtr on success or NULL on failure
>>
>>   An example of backup xml:
>>
>>      <domainbackup>
>>        <uuid>54c70d40-26bb-48cd-9639-b3a1e9adf650</uuid>
>>        <description>Any string</description>
>>        <disks>
>>          <disk name='hda'>
>>              <target>
>>              ... nbd server parameters for 'nbd-server-start' command
>> followed by
>>              'blockdev-backup' and 'nbd-server-add' QMP commands
>>               OR some other suitable target
>>              </target>
>>          </disk>
>>          <disk name='hdb'>
>>              <target>
>>              ... nbd server parameters
>>              </target>
>>          </disk>
>>        </disks>
>>      </domainbackup>
> I'm assuming an 'unmanaged' backup would not be shown when calling
> virDomainBackupList later on ?

Exactly

>
> Also with the QEMU built-in NBD server, you just have a single
> nbd-server-start to do, and that one server will export multiple
> disks as named exports. So you wouldn't repeat the NBD server
> parameters for all disks.

Got it.

>> --------------------------------------------------------------------------------
>> int virDomainBackupList(virDomainPtr domain,
>>                          virBackupPtr ** backups,
>>                          unsigned int flags)
>>
>>   Collect the list of domain backups for the given domain, and allocate an
>> array
>>   to store those objects
>>
>>     - domain: a domain object
>>     - backups: pointer to variable to store the array containing backup
>> objects,
>>       or NULL if the list is not required (just returns number of backups)
>>     - flags: bitwise-OR of virBackupListFlags
>>     - returns: the number of backups on success or -1 on failure
>>
>>    enum virBackupListFlags {
>>
>>      VIR_BACKUP_LIST_FULL = 1,
>>      VIR_BACKUP_LIST_LATEST = 2,
>>      ...
>>
>>    }
>>
>> --------------------------------------------------------------------------------
>> int virBackupListChildren(virBackupPtr backup,
>>                            virBackupPtr ** backups,
>>                            unsigned int flags)
>>
>>   Collect the list of child backups for the given backup, and allocate an
>> array
>>   to store them
>>
>>     - backup: a backup object
>>     - backups: pointer to variable to store the array containing backup
>> objects,
>>       or NULL if the list is not required (just returns number of backups)
>>     - flags: bitwise-OR of virBackupListFlags
>>     - returns: the number of backups on success or -1 on failure
>>
>> --------------------------------------------------------------------------------
>> int virBackupRestore(const char * xmlDesc,
>>                       unsigned int flags)
> For the "managed backups" case it feels like this should be accepting
> a virDomainBackupPtr rather than an xmlDesc string.

Not sure because I would like to have an ability to restore not every 
disk a backup has but sometimes selected only.

>
> For the "unmanaged backups", then IIUC, we would need to have
> a virDOmainPtr and the xmlDesc. So probably want a separate
> API for that. virBackupRestoreUnmanaged ?
>

Makes sense.

>>   Restore a domain from a given backup.
>>
>>     - xmlDesc: string containing an XML description of what to restore. It
>> can
>>       repeate complete backup xml or specify some part of disks to restore.
>>     - flags: bitwise-OR of virBackupRestoreFlags
>>     - returns: 0 on success or -1 on failure
>>
>>    enum virBackupRestoreFlags {
>>
>>      VIR_BACKUP_RESTORE_NEW_DOMAIN = 1,
>>      VIR_BACKUP_RESTORE_REWRITE_EXISTING_DISK = 2,
>>      ...
>>    }
>>
>>   An example of restore xml:
>>
>>      <domainbackup>
>>        <uuid>54c70d40-26bb-48cd-9639-b3a1e9adf650</uuid>
>>        <disks>
>>          <disk name='vda'>
>>              <target>
>>              ... volume, file, or any possible target, (if absent, reuses
>> current
>>              disk target)
>>              </target>
>>          </disk>
>>          <disk name='vdb'>
>>              <target>
>>              ...
>>              </target>
>>          </disk>
>>        </disks>
>>      </domainbackup>
>>
>> --------------------------------------------------------------------------------
>> int virBackupDelete(virBackupPtr backup,
>>                      unsigned int flags)
>>
>>   Delete the specified backup
>>
>>     - backup: a backup object
>>     - flags: bitwise-OR of virBackupDeleteFlags
>>     - returns: 0 on success or -1 on failure
>>
>>    enum virBackupDeleteFlags {
>>
>>      VIR_BACKUP_DELETE_ALL = 1,
>>      VIR_BACKUP_DELETE_ALL_CHILDREN = 2,
>>      ...
>>    }
>>
>> --------------------------------------------------------------------------------
>> int virBackupFree(virBackupPtr backup)
>>
>>   Free the backup object. The backup itself is not modified. The data
>> structure
>>   is freed and should not be used thereafter.
>>
>>     - backup: a backup object
>>     - returns: 0 on success or -1 on failure
>>
>> --------------------------------------------------------------------------------
>> char* virBackupGetXMLDesc(virBackupPtr backup,
>>                            unsigned int flags)
>>
>>   Provide an XML description of the backup
>>
>>     - backup: a backup object
>>     - flags: bitwise-OR of virDomainXMLFlags
>>     - returns: a 0 terminated UTF-8 encoded XML instance, or NULL in case of
>>       error. The caller must free() the returned value
>>
>>   An example of dumped xml:
>>
>>      <domainbackup>
>>        <uuid>54c70d40-26bb-48cd-9639-b3a1e9adf650</uuid>
>>        <creationTime>1270477159</creationTime>
>>        <description>Any string</description>
>>        <parent>
>> <uuid>d2ee2566-bef2-408f-ac7a-eb8004186074</uuid>
>>        <parent>
>>        <disks>
>>          <disk name='vda'>
>>              <target>
>>              ... volume, file, or any possible target
>>              </target>
>>          </disk>
>>          <disk name='vdb'>
>>              <target>
>>              ...
>>              </target>
>>          </disk>
>>        </disks>
>>      </domainbackup>
>>
>> --------------------------------------------------------------------------------
>> virBackupPtr virBackupLookupByUUID(const char * uuid,
>>                                     unsigned int flags)
>>
>>   Try to lookup a backup by its UUID
>>
>>     - uuid: a backup uuid
>>     - flags: for future use
>>     - returns: an opaque virBackupPtr on success or NULL on failure
>>
>> --------------------------------------------------------------------------------
>> virDomainPtr virBackupGetDomain(virBackupPtr backup)
>>
>>   Provide the domain pointer associated with a backup. The reference counter
>> on
>>   the domain is not increased by this call
>>
>>     - backup: a backup object
>>     - returns: a domain object on success or NULL on failure
>>
>> --------------------------------------------------------------------------------
>> int virBackupFinishJob(virBackupPtr backup,
>>                         unsigned int flags)
>>
>>   Finish async job associated with specified backup
>>
>>     - backup: a backup object
>>     - flags: bitwise-OR of virBackupDeleteFlags
>>     - returns: 0 on if the job for the specified backup was finished or
>> cancelled
>>       successfully or -1 otherwise
>>
>>    enum virBackupFinishJobFlags {
>>
>>      VIR_BACKUP_FINISH_JOB_CANCEL = 1,
>>      VIR_BACKUP_FINISH_JOB_CHECK = 2,
>>      ...
>>    }
> Probablt want a corresponding virBackupAbortJob too.

Makes sense as well

>
>>
>> --------------------------------------------------------------------------------
>> int virBackupGetParameters(virBackupPtr backup,
>>                             virTypedParameterPtr params,
>>                             int * nparams,
>>                             unsigned int flags)
>>
>>   Get backup parameters. On input, @nparams gives the size of the @params
>> array;
>>   on output, @nparams gives how many slots were filled with parameter
>>   information, which might be less but will not exceed the input value
>>
>>     - backup: a backup object
>>     - params: pointer to backup parameter object (return value, allocated by
>> the
>>       caller)
>>     - nparams: pointer to number of blkio parameters; input and output
>>     - flags: for future use
>>     - returns: 0 on success or -1 on failure
>>
>> --------------------------------------------------------------------------------
>> int virDomainSetDefaultTarget(virDomainPtr domain,
>>                                const char * xmlDesc,
>>                                unsigned int flags)
>>
>>   Set default store target for backup, snapshot, managed saved state metadata
>>
>>     - domain: a domain object
>>     - xmlDesc: string containing an XML description of the backup
>>     - flags: bitwise-OR of virDomainDeviceModifyFlags
>>     - returns: 0 on success or -1 on failure
> Not sure I understand what this is doing, but probably not a big deal.

I was trying to addess what Eric Blake said in this thread earlier 
regarding a default pool.

>> Also, virDomainUndefineFlagsValues should be expanded with
>> VIR_DOMAIN_UNDEFINE_BACKUP and virDomainUndefineFlags implementations should
>> take into account this flag when undefining domains.
> Overall I think this looks like a reasonable API design to start
> implementing.

Thanks a lot.
Will start shortly.

> Regards,
> Daniel




More information about the libvir-list mailing list