[libvirt] [PATCH 2/2] snapshot: avoid accidental renames with snapshot-edit

Daniel Veillard veillard at redhat.com
Mon Oct 10 02:24:28 UTC 2011


On Fri, Oct 07, 2011 at 04:35:29PM -0600, Eric Blake wrote:
> I was a bit surprised that 'virsh snapshot-edit dom name' silently
> allowed me to clone things, while still telling me the old name,
> especially since other commands like 'virsh edit dom' reject rename
> attempts (*).  This fixes things to be more explicit.
> 
> (*) Technically, 'virsh edit dom' relies on virDomainDefineXML
> behavior, which rejects attempts to mix a new name with existing
> uuid or new uuid with existing name, but you can create a new
> domain by changing both uuid and name.  On the other hand, while
> snapshot-edit --clone is a true clone, creating a new domain
> would also have to decide whether to clone snapshot metadata,
> managed save, and any other secondary data related to the domain.
> Domain renames are not trivial either.
> 
> * tools/virsh.c (cmdSnapshotEdit): Add --rename, --clone.
> * tools/virsh.pod (snapshot-edit): Document them.
> ---
>  tools/virsh.c   |   45 ++++++++++++++++++++++++++++++++++++++++-----
>  tools/virsh.pod |    6 ++++++
>  2 files changed, 46 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 20b3dc5..7151694 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -12830,6 +12830,8 @@ static const vshCmdOptDef opts_snapshot_edit[] = {
>      {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
>      {"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
>      {"current", VSH_OT_BOOL, 0, N_("also set edited snapshot as current")},
> +    {"rename", VSH_OT_BOOL, 0, N_("allow renaming an existing snapshot")},
> +    {"clone", VSH_OT_BOOL, 0, N_("allow cloning to new name")},
>      {NULL, 0, 0, NULL}
>  };
> 
> @@ -12838,13 +12840,23 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
>  {
>      virDomainPtr dom = NULL;
>      virDomainSnapshotPtr snapshot = NULL;
> +    virDomainSnapshotPtr edited = NULL;
>      const char *name;
> +    const char *edited_name;
>      bool ret = false;
>      char *tmp = NULL;
>      char *doc = NULL;
>      char *doc_edited = NULL;
>      unsigned int getxml_flags = VIR_DOMAIN_XML_SECURE;
>      unsigned int define_flags = VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
> +    bool rename_okay = vshCommandOptBool(cmd, "rename");
> +    bool clone_okay = vshCommandOptBool(cmd, "clone");
> +
> +    if (rename_okay && clone_okay) {
> +        vshError(ctl, "%s",
> +                 _("--rename and --clone are mutually exclusive"));
> +        return false;
> +    }
> 
>      if (vshCommandOptBool(cmd, "current"))
>          define_flags |= VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT;
> @@ -12867,8 +12879,6 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
>      doc = virDomainSnapshotGetXMLDesc(snapshot, getxml_flags);
>      if (!doc)
>          goto cleanup;
> -    virDomainSnapshotFree(snapshot);
> -    snapshot = NULL;
> 
>      /* strstr is safe here, since xml came from libvirt API and not user */
>      if (strstr(doc, "<state>disk-snapshot</state>"))
> @@ -12899,13 +12909,36 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
>      }
> 
>      /* Everything checks out, so redefine the xml.  */
> -    snapshot = virDomainSnapshotCreateXML(dom, doc_edited, define_flags);
> -    if (!snapshot) {
> +    edited = virDomainSnapshotCreateXML(dom, doc_edited, define_flags);
> +    if (!edited) {
>          vshError(ctl, _("Failed to update %s"), name);
>          goto cleanup;
>      }
> 
> -    vshPrint(ctl, _("Snapshot %s edited.\n"), name);
> +    edited_name = virDomainSnapshotGetName(edited);
> +    if (STREQ(name, edited_name)) {
> +        vshPrint(ctl, _("Snapshot %s edited.\n"), name);
> +    } else if (clone_okay) {
> +        vshPrint(ctl, _("Snapshot %s cloned to %s.\n"), name,
> +                 edited_name);
> +    } else {
> +        unsigned int delete_flags;
> +
> +        delete_flags = VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY;
> +        if (virDomainSnapshotDelete(rename_okay ? snapshot : edited,
> +                                    delete_flags) < 0) {
> +            virshReportError(ctl);
> +            vshError(ctl, _("Failed to clean up %s"),
> +                     rename_okay ? name : edited_name);
> +            goto cleanup;
> +        }
> +        if (!rename_okay) {
> +            vshError(ctl, _("Must use --rename or --clone to change %s to %s"),
> +                     name, edited_name);
> +            goto cleanup;
> +        }
> +    }
> +
>      ret = true;
> 
>  cleanup:
> @@ -12917,6 +12950,8 @@ cleanup:
>      }
>      if (snapshot)
>          virDomainSnapshotFree(snapshot);
> +    if (edited)
> +        virDomainSnapshotFree(edited);
>      if (dom)
>          virDomainFree(dom);
>      return ret;
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index 1f7c76f..3351fe0 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -1952,6 +1952,7 @@ With I<snapshotname>, this is a request to make the existing named
>  snapshot become the current snapshot, without reverting the domain.
> 
>  =item B<snapshot-edit> I<domain> I<snapshotname> [I<--current>]
> +{[I<--rename>] | [I<--clone>]}
> 
>  Edit the XML configuration file for I<snapshotname> of a domain.  If
>  I<--current> is specified, also force the edited snapshot to become
> @@ -1968,6 +1969,11 @@ except that it does some error checking.
>  The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment
>  variables, and defaults to C<vi>.
> 
> +If I<--rename> is specified, then the edits can change the snapshot
> +name.  If I<--clone> is specified, then changing the snapshot name
> +will create a cloned snapshot.  If neither is specified, then the
> +edits must not change the snapshot name.
> +
>  =item B<snapshot-list> I<domain> [{I<--parent> | I<--roots> | I<--tree>}]
>  [I<--metadata>]
> 

  ACK, looks fine,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list