diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 7650535b48573615d48fd7af9afc1ceafb41ceda..edbbc34e0000a6668041fca96477a40ae0587d6e 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -3674,6 +3674,11 @@ static const vshCmdOptDef opts_undefine[] = { .type = VSH_OT_BOOL, .help = N_("remove all associated storage volumes (use with caution)") }, + {.name = "delete-snapshots", + .type = VSH_OT_BOOL, + .help = N_("delete snapshots associated with volume(s), requires " + "--remove-all-storage (must be supported by storage driver)") + }, {.name = "wipe-storage", .type = VSH_OT_BOOL, .help = N_("wipe data on the removed volumes") @@ -3703,11 +3708,13 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) const char *name = NULL; /* Flags to attempt. */ unsigned int flags = 0; + unsigned int vol_flags = 0; /* User-requested actions. */ bool managed_save = vshCommandOptBool(cmd, "managed-save"); bool snapshots_metadata = vshCommandOptBool(cmd, "snapshots-metadata"); bool wipe_storage = vshCommandOptBool(cmd, "wipe-storage"); bool remove_all_storage = vshCommandOptBool(cmd, "remove-all-storage"); + bool delete_snapshots = vshCommandOptBool(cmd, "delete-snapshots"); bool nvram = vshCommandOptBool(cmd, "nvram"); /* Positive if these items exist. */ int has_managed_save = 0; @@ -3736,6 +3743,8 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) size_t j; virshControlPtr priv = ctl->privData; + VSH_REQUIRE_OPTION("delete-snapshots", "remove-all-storage"); + ignore_value(vshCommandOptStringQuiet(ctl, cmd, "storage", &vol_string)); if (!(vol_string || remove_all_storage) && wipe_storage) { @@ -3745,6 +3754,9 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) return false; } + if (delete_snapshots) + vol_flags |= VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS; + if (managed_save) { flags |= VIR_DOMAIN_UNDEFINE_MANAGED_SAVE; managed_save_safe = true; @@ -4011,7 +4023,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) } /* delete the volume */ - if (virStorageVolDelete(vols[i].vol, 0) < 0) { + if (virStorageVolDelete(vols[i].vol, vol_flags) < 0) { vshError(ctl, _("Failed to remove storage volume '%s'(%s)"), vols[i].target, vols[i].source); ret = false; diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c index 3408bee04c3a91113e6f63df73e82e2c1a854250..7932ef2be2f346922a0547efb21cdbfb05b321d3 100644 --- a/tools/virsh-volume.c +++ b/tools/virsh-volume.c @@ -887,6 +887,11 @@ static const vshCmdOptDef opts_vol_delete[] = { .type = VSH_OT_STRING, .help = N_("pool name or uuid") }, + {.name = "delete-snapshots", + .type = VSH_OT_BOOL, + .help = N_("delete snapshots associated with volume (must be " + "supported by storage driver)") + }, {.name = NULL} }; @@ -896,11 +901,16 @@ cmdVolDelete(vshControl *ctl, const vshCmd *cmd) virStorageVolPtr vol; bool ret = true; const char *name; + bool delete_snapshots = vshCommandOptBool(cmd, "delete-snapshots"); + unsigned int flags = 0; if (!(vol = virshCommandOptVol(ctl, cmd, "vol", "pool", &name))) return false; - if (virStorageVolDelete(vol, 0) == 0) { + if (delete_snapshots) + flags |= VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS; + + if (virStorageVolDelete(vol, flags) == 0) { vshPrint(ctl, _("Vol %s deleted\n"), name); } else { vshError(ctl, _("Failed to delete vol %s"), name); diff --git a/tools/virsh.pod b/tools/virsh.pod index 107fc324e5ca7518b6e5fdf8402defd02ba4b4db..9456db84e3d5a61e3b1f930f2b77a5715bf01815 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2295,7 +2295,9 @@ Output the device used for the TTY console of the domain. If the information is not available the processes will provide an exit code of 1. =item B I [I<--managed-save>] [I<--snapshots-metadata>] -[I<--nvram>] [ {I<--storage> B | I<--remove-all-storage>} I<--wipe-storage>] +[I<--nvram>] +[ {I<--storage> B | I<--remove-all-storage> [I<--delete-snapshots>]} +I<--wipe-storage>] Undefine a domain. If the domain is running, this converts it to a transient domain, without stopping it. If the domain is inactive, @@ -2330,6 +2332,11 @@ Example: --storage vda,/path/to/storage.img The I<--remove-all-storage> flag specifies that all of the domain's storage volumes should be deleted. +The I<--delete-snapshots> flag specifies that any snapshots associated with +the storage volume should be deleted as well. Requires the +I<--remove-all-storage> flag to be provided. Not all storage drivers +support this option, presently only rbd. + The flag I<--wipe-storage> specifies that the storage volumes should be wiped before removal. @@ -3461,12 +3468,17 @@ where the data blocks are copied only when modified. If this is not possible, the copy fails. =item B [I<--pool> I] I +[I<--delete-snapshots>] Delete a given volume. I<--pool> I is the name or UUID of the storage pool the volume is in. I is the name or key or path of the volume to delete. +The I<--delete-snapshots> flag specifies that any snapshots associated with +the storage volume should be deleted as well. Not all storage drivers +support this option, presently only rbd. + =item B [I<--pool> I] [I<--offset> I] [I<--length> I] I I