Hi!

On Mon, Jul 02, 2007 at 02:30:55PM +0200, Fabio Massimo Di Nitto wrote:
> I am seeing different issues such as:
> 
> 1) take a fresh disk with no lvm
> 2) install using automatic lvm setup and it will work
> 3) install on it again this time not using lvm and it will work
> 4) install again this time using lvm and it will fail
> 
> The problem is that at #4 the disk has no partitions type LVM but the lvm
> metadata from #2 are still there.
> 
> pvscan still works but all other lvm operations will correctly report that 
> there
> is an error.
> 
> Basically #3 did not wipe the disk properly.
> [...]
> I have different ideas on how to approach the problem but in one way or 
> another
> they might hit other kinds of installations (Colin Watson mentioned low-mem as
> one of them).
> 
> My suggestion is:
> - Make partman-auto depends on the proper bits that it is actually using.
> - Add code to modprobe/verify that dm-mod is available.
> - Fix dm_wipe_lvm to not require dmsetup to detect the volumes and use lvm2
>   tools instead (I am not happy to execute vgchanges if we can avoid it).

The attached patch partially implements these suggestions and removes
bits of duplicated code in partman-partitioning and partman-auto.
Here's the details:

The creation of a new label for a disk (thus wiping any partitions) has
been factored out in create_new_label() in partman-base.
    
This function is then used by :
 * partman-partinioning/storage_device/label/do_option ;
 * partman-auto/auto-shared:wipe_disk().

create_new_label() uses dm_wipe_disk() when applicable and falls back to
lvm_wipe_disk() if dm_mod is not loaded.  The later does not require
dmsetup or the activation of the devices.

Both dm_wipe_disk() and lvm_wipe_disk() might require partman to be
restarted in order to get its state properly refreshed.  This has been
factored out in partman-base/definitions.sh:updated_parted().

In order to keep some modularity, dm_wipe_disk() has been moved from
partman-auto to partman-crypto:crypto_tools.sh.  In a similar fashion,
lvm_wipe_disk() has been added to partman-lvm:lvm_tools.sh.

The value added by the refactoring is less than it could possibly be,
though: once LVM has been configured, the devices are "locked" for
partman and the creation of a new label will prevented.  This check
could probably be relaxed with these new changes.

I have tested various cases and this patch will make d-i work correctly
with Fabio's scenario.  I would like some reviews though as I am far
from being a partman guru.

Cheers,
-- 
Jérémy Bobbio                        .''`. 
[EMAIL PROTECTED]                    : :Ⓐ  :  # apt-get install anarchism
                                    `. `'` 
                                      `-   
commit e0a88b79f0933e561028b9c48a6ed2f6004fac40
Author: Jérémy Bobbio <[EMAIL PROTECTED]>
Date:   Wed Oct 24 21:13:56 2007 +0200

    Fix the creation of a new partition label when crypto or LVM are used
    
    In order to make the creation of a new partition label (manually or
    through guided partitioning) correctly remove LVM and crypto metadata
    (see #396023 and #425829) the operation has been factored out in
    create_new_label() in partman-base.
    
    This function is then used by :
     * partman-partinioning/storage_device/label/do_option ;
     * partman-auto/auto-shared:wipe_disk().
    
    create_new_label() uses dm_wipe_disk() when applicable and falls back to
    lvm_wipe_disk() if dm_mod is not loaded.  The later does not require
    dmsetup or the activation of the devices.

    Both dm_wipe_disk() and lvm_wipe_disk() might require partman to be
    restarted in order to get its state properly refreshed.  This has been
    factored out in partman-base/definitions.sh:updated_parted().
    
    In order to keep some modularity, dm_wipe_disk() has been moved from
    partman-auto to partman-crypto:crypto_tools.sh.  In a similar fashion,
    lvm_wipe_disk() has been added to partman-lvm:lvm_tools.sh.
    
    The value added by the refactoring is less than it could possibly be,
    though: once LVM has been configured, the devices are "locked" for
    partman and the creation of a new label will prevented.  This check
    could probably be relaxed with these new changes.

diff --git a/packages/partman/partman-auto/auto-shared.sh 
b/packages/partman/partman-auto/auto-shared.sh
index dc63eee..ec38c7a 100644
--- a/packages/partman/partman-auto/auto-shared.sh
+++ b/packages/partman/partman-auto/auto-shared.sh
@@ -1,303 +1,13 @@
 ## this file contains a bunch of shared code between partman-auto
 ## and partman-auto-lvm.
 
-# Gets the major and minor device numbers of a device passed as $1
-# and puts them in $MAJOR and $MINOR.
-dev_get_major_minor() {
-       local dev stats
-       dev="$1"
-
-       if [ -z "$dev" ]; then
-               return 1
-       fi
-
-       stats=$(ls -al "$dev" | sed -e 's/[[:space:],]\+/ /g')
-       MAJOR=$(echo "$stats" | cut -d' ' -f5)
-       MINOR=$(echo "$stats" | cut -d' ' -f6)
-
-       if [ -z "$MAJOR" ] || [ -z "$MINOR" ]; then
-               return 1
-       fi
-
-       return 0
-}
-
-# Makes sure that parted has no stale info
-dm_update_parted() {
-       local restart tmpdev tmppart realdev
-
-       restart="0"
-       for tmpdev in $DEVICES/*; do
-               for tmppart in $tmpdev/*; do
-                       if [ ! -d "$tmppart" ]; then
-                               continue
-                       fi
-
-                       if [ ! -e "$tmppart/crypt_active" ]; then
-                               continue
-                       fi
-
-                       if [ ! -e "$(cat "$tmppart/crypt_active")" ]; then
-                               rm -f "$tmppart/crypt_active"
-                               rm -f "$tmppart/locked"
-                               restart="1"
-                       fi
-               done
-
-               realdev=$(cat $tmpdev/device)
-               if ! $(echo "$realdev" | grep -q "/dev/mapper/"); then
-                       continue
-               fi
-
-               if [ -b "$realdev" ]; then
-                       continue
-               fi
-
-               rm -rf $tmpdev
-               restart="1"
-       done
-
-       if [ $restart ]; then
-               stop_parted_server
-               restart_partman || return 1
-       fi
-
-       return 0
-}
-
-# Given a lvm device (excluding the /dev/mapper/ part), will gather data on
-# the LVM config, prompt the user and then remove the VG along with all the
-# LV's and PV's which belong to that VG.
-dm_wipe_lvm() {
-       local dev vg pv pvs lv lvs vgtext lvtext pvtext
-       dev="$1"
-
-       # First check that the device exists, it's not an error if it doesn't
-       # since one call to this function can wipe several LV's
-       if [ ! -b "/dev/mapper/$dev" ]; then
-               return 0
-       fi
-
-       if [ ! -e /lib/partman/lvm_tools.sh ]; then
-               return 1
-       fi
-
-       . /lib/partman/lvm_tools.sh
-
-       # We get a device like mainvg-swaplv as $1, let's figure out the VG
-
-       # Make sure that the device includes at least one dash
-        if [ "$(echo -n "$dev" | tr -d -)" = "$dev" ]; then
-                return 1
-       fi
-
-        # Split volume group from logical volume.
-        vg=$(echo ${dev} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')
-        # Reduce padded --'s to -'s
-        vg=$(echo ${vg} | sed -e 's#--#-#g')
-       if [ -z "$vg" ]; then
-               return 1
-       fi
-       pvs=$(vg_list_pvs $vg)
-       lvs=$(vg_list_lvs $vg)
-
-       # Ask for permission to erase LVM volumes 
-       vgtext="$vg"
-       pvtext=""
-       for pv in $pvs; do
-               pvtext="${pvtext:+$pvtext, }$pv"
-       done
-       lvtext=""
-       for lv in $lvs; do
-               lvtext="${lvtext:+$lvtext, }$lv"
-       done
-
-       db_subst partman-auto/purge_lvm_from_device VGTARGETS "$vgtext"
-       db_subst partman-auto/purge_lvm_from_device LVTARGETS "$lvtext"
-       db_subst partman-auto/purge_lvm_from_device PVTARGETS "$pvtext"
-       db_input critical partman-auto/purge_lvm_from_device
-       db_go || return 1
-       db_get partman-auto/purge_lvm_from_device
-       if [ "$RET" != "true" ]; then
-               return 1
-       fi
-
-       # Remove the LV's
-       for lv in $lvs; do
-               lv_delete $vg $lv
-       done
-
-       # Remove the VG
-       vg_delete $vg
-
-       # Remove the PV's
-       for pv in $pvs; do
-               pv_delete $pv
-               partman_unlock_unit $pv
-       done
-
-       return 0
-}
-
-# Given a cryptodev (minus the /dev/mapper/ part), will prompt the user and
-# then remove the device.
-dm_wipe_crypto() {
-       local dev
-       dev="$1"
-
-       # Ask for permission to erase crypto volumes 
-       db_subst partman-auto/purge_crypto_from_device TARGET "$dev"
-       db_input critical partman-auto/purge_crypto_from_device
-       db_go || return 1
-       db_get partman-auto/purge_crypto_from_device
-       if [ "$RET" != "true" ]; then
-               return 1
-       fi
-
-       dmsetup remove "$dev"
-       return $?
-}
-
-# Given a dm device (minus the /dev/mapper/ part), will recursively remove
-# all devices which depend on it and then the device itself.
-dm_wipe_dev() {
-       local dev deps dep name type
-       dev="$1"
-
-       if [ ! -e "/dev/mapper/$dev" ]; then
-               return 0
-       fi
-
-       dev_get_major_minor "/dev/mapper/$dev" || return 1
-       deps=$(dmsetup deps | grep "($MAJOR, $MINOR)" | cut -d: -f1)
-       for dep in $deps; do
-               if [ ! -e "/dev/mapper/$dep" ]; then
-                       continue
-               fi
-
-               dev_get_major_minor "/dev/mapper/$dep" || return 1
-               name=$(dmsetup info -j$MAJOR -m$MINOR | grep "Name:" | \
-                       cut -d: -f2 | sed -e 's/[[:space:]]//g')
-               if [ -z "$name" ]; then
-                       return 1
-               fi
-
-               dm_wipe_dev "$name" || return 1
-       done
-
-       type=$(dmsetup table | grep "^$dev:" | cut -d' ' -f4)
-       if [ -z "$type" ]; then
-               return 1
-       elif [ "$type" = crypt ]; then
-               dm_wipe_crypto "$dev" || return 1
-       else
-               dm_wipe_lvm "$dev" || return 1
-       fi
-
-       return 0
-}
-
-# Wipes any dm devices from a disk (LVM and/or crypto)
-# Given an argument like /dev/hda, /dev/hda1 and /dev/hda2 are also wiped...
-# Normally you wouldn't want to use this function, 
-# but wipe_disk() which will also call this function.
-dm_wipe_disk() {
-       local dev realdev devs check checkdev provide provides restart tmpdev 
tmppart
-       dev="$1"
-
-       if [ -z "$dev" ]; then
-               return 1
-       fi
-
-       realdev=$(mapdevfs "$(cat $dev/device)")
-       devs=$(ls ${realdev}* 2>/dev/null)
-
-       # Given e.g. /dev/hda we check /dev/hda, /dev/hda1, etc...
-       for check in $devs; do
-               checkdev=$(readlink -f "$check")
-               if [ ! -e "$checkdev" ]; then
-                       continue
-               fi
-
-               dev_get_major_minor "$checkdev" || return 1
-
-               provides=$(dmsetup deps | grep "($MAJOR, $MINOR)" | cut -d: -f1)
-
-               if [ -z "$provides" ]; then
-                       continue
-               fi
-
-               for provide in $provides; do
-                       dm_wipe_dev $provide || return 1
-               done
-       done
-       
-       dm_update_parted || return 1
-       return 0
-}
-
 wipe_disk() {
        local dev
        dev="$1"
 
-       if [ -z "$dev" ]; then
-               return 1
-       fi
-
-       dm_wipe_disk "$dev" || return 1
+       create_new_label "$dev" || return 1
 
        cd $dev || return 1
-       open_dialog LABEL_TYPES
-       types=$(read_list)
-       close_dialog
-
-       label_type=$(default_disk_label)
-
-       if ! expr "$types" : ".*${label_type}.*" >/dev/null; then
-               label_type=msdos # most widely used
-       fi
-       
-       # Use gpt instead of msdos disklabel for disks larger than 2TB
-       if expr "$types" : ".*gpt.*" >/dev/null; then
-               if [ "$label_type" = msdos ] ; then
-                       disksize=$(cat size)
-                       if $(longint_le $(human2longint 2TB) $disksize) ; then
-                               label_type=gpt
-                       fi
-               fi
-       fi
-
-       if [ "$label_type" = sun ]; then
-               db_input critical partman/confirm_write_new_label
-               db_go || exit 0
-               db_get partman/confirm_write_new_label
-               if [ "$RET" = false ]; then
-                       db_reset partman/confirm_write_new_label
-                       exit 1
-               fi
-               db_reset partman/confirm_write_new_label
-       fi
-       
-       open_dialog NEW_LABEL "$label_type"
-       close_dialog
-       
-       if [ "$label_type" = sun ]; then
-               # write the partition table to the disk
-               disable_swap
-               open_dialog COMMIT
-               close_dialog
-               sync
-               # reread it from there
-               open_dialog UNDO
-               close_dialog
-               enable_swap
-       fi
-
-       # Different types partition tables support different visuals.  Some
-       # have partition names other don't have, some have extended and
-       # logical partitions, others don't.  Hence we have to regenerate the
-       # list of the visuals
-       rm -f visuals
 
        free_space=''
        open_dialog PARTITIONS
diff --git a/packages/partman/partman-auto/debian/changelog 
b/packages/partman/partman-auto/debian/changelog
index 0a0a6a6..874186c 100644
--- a/packages/partman/partman-auto/debian/changelog
+++ b/packages/partman/partman-auto/debian/changelog
@@ -1,3 +1,13 @@
+partman-auto (71) UNRELEASED; urgency=low
+
+  * Use create_new_label() in wipe_disk().  Requires partman-base (>> 110).
+    (Closes: #425829)
+  * Move dm_update_parted to partman-base.
+  * Move dm_wipe_disk and its dependencies to partman-crypto.
+  * Remove unused partman-auto/cannot_purge_lvm_from_device template.
+
+ -- Jérémy Bobbio <[EMAIL PROTECTED]>  Wed, 24 Oct 2007 18:49:04 +0200
+
 partman-auto (70) unstable; urgency=low
 
   [ Frans Pop ]
diff --git a/packages/partman/partman-auto/debian/control 
b/packages/partman/partman-auto/debian/control
index 7eeced1..d730deb 100644
--- a/packages/partman/partman-auto/debian/control
+++ b/packages/partman/partman-auto/debian/control
@@ -9,5 +9,5 @@ Vcs-Svn: 
svn://svn.debian.org/d-i/trunk/packages/partman/partman-auto
 Package: partman-auto
 XC-Package-Type: udeb
 Architecture: any
-Depends: ${misc:Depends}, di-utils, partman-base (>= 99), 
partman-basicfilesystems, partman-ext3
+Depends: ${misc:Depends}, di-utils, partman-base (>> 110), 
partman-basicfilesystems, partman-ext3
 Description: Automatically partition storage devices (partman)
diff --git a/packages/partman/partman-auto/debian/partman-auto.templates 
b/packages/partman/partman-auto/debian/partman-auto.templates
index d7b28c8..c734a24 100644
--- a/packages/partman/partman-auto/debian/partman-auto.templates
+++ b/packages/partman/partman-auto/debian/partman-auto.templates
@@ -59,13 +59,6 @@ _Description: Remove existing crypto volume data?
  Note that this will also permanently erase any data currently on the
  crypto volume.
 
-Template: partman-auto/cannot_purge_lvm_from_device
-Type: error
-_Description: LVM physical volume already exists on the selected device
- The selected device already contains one or more LVM physical
- volumes which cannot be removed. It is therefore not possible to
- automatically partition this device.
-
 Template: partman-auto/disk
 Type: string
 Description: for internal use; can be preseeded
diff --git a/packages/partman/partman-base/debian/changelog 
b/packages/partman/partman-base/debian/changelog
index 9854522..0498250 100644
--- a/packages/partman/partman-base/debian/changelog
+++ b/packages/partman/partman-base/debian/changelog
@@ -1,3 +1,12 @@
+partman-base (111) UNRELEASED; urgency=low
+
+  * Add update_parted() (from partman-auto) to definitions.sh.
+  * Add create_new_label() in definitions.sh.  This function is used to create
+    a new label on a disk and wipes its content (e.g. LVM and crypto)
+    accordingly.  Require partman-partitining (>> 0.52) to make use of it.
+
+ -- Jérémy Bobbio <[EMAIL PROTECTED]>  Wed, 24 Oct 2007 18:52:19 +0200
+
 partman-base (110) unstable; urgency=low
 
   [ Colin Watson ]
diff --git a/packages/partman/partman-base/debian/control 
b/packages/partman/partman-base/debian/control
index cd875d3..1c0eb16 100644
--- a/packages/partman/partman-base/debian/control
+++ b/packages/partman/partman-base/debian/control
@@ -9,7 +9,7 @@ Vcs-Svn: 
svn://svn.debian.org/d-i/trunk/packages/partman/partman-base
 Package: partman-base
 XC-Package-Type: udeb
 Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, partman-utils, 
partman-partitioning, partman-target, archdetect, harddrive-detection, 
di-utils-mapdevfs, di-utils (>= 1.15)
+Depends: ${shlibs:Depends}, ${misc:Depends}, partman-utils, 
partman-partitioning (>> 0.52), partman-target, archdetect, 
harddrive-detection, di-utils-mapdevfs, di-utils (>= 1.15)
 Provides: ${provides}
 XB-Installer-Menu-Item: ${menuitemnum}
 Description: Partition the storage devices (partman)
diff --git a/packages/partman/partman-base/definitions.sh 
b/packages/partman/partman-base/definitions.sh
index 3aac718..71a8046 100644
--- a/packages/partman/partman-base/definitions.sh
+++ b/packages/partman/partman-base/definitions.sh
@@ -296,6 +296,50 @@ restart_partman () {
        db_progress STOP
 }
 
+# Make sure that parted has no stale info
+# (used after crypto/LVM cleanup)
+update_parted() {
+       local restart tmpdev tmppart realdev
+
+       restart="0"
+       for tmpdev in $DEVICES/*; do
+               for tmppart in $tmpdev/*; do
+                       if [ ! -d "$tmppart" ]; then
+                               continue
+                       fi
+
+                       if [ ! -e "$tmppart/crypt_active" ]; then
+                               continue
+                       fi
+
+                       if [ ! -e "$(cat "$tmppart/crypt_active")" ]; then
+                               rm -f "$tmppart/crypt_active"
+                               rm -f "$tmppart/locked"
+                               restart="1"
+                       fi
+               done
+
+               realdev=$(cat $tmpdev/device)
+               if ! $(echo "$realdev" | grep -q "/dev/mapper/"); then
+                       continue
+               fi
+
+               if [ -b "$realdev" ]; then
+                       continue
+               fi
+
+               rm -rf $tmpdev
+               restart="1"
+       done
+
+       if [ $restart ]; then
+               stop_parted_server
+               restart_partman || return 1
+       fi
+
+       return 0
+}
+
 update_partition () {
        local u
        cd $1
@@ -1001,6 +1045,91 @@ partman_lock_unit() {
        done
 }
 
+create_new_label() {
+       local dev default_type chosen_type types
+       dev="$1"
+
+       if [ -z "$dev" ]; then
+               return 1
+       fi
+
+       # If we have dm-mod, use dmsetup to cleanup LVM and crypto partitions
+       if lsmod | grep -q '^dm_mod ' && [ -f /lib/partman/crypto_tools.sh ]; 
then
+               . /lib/partman/crypto_tools.sh
+               dm_wipe_disk "$dev" || return 1
+       elif [ -f /lib/partman/lvm_tools.sh ]; then
+               # Remove LVM devices using plain LVM tools
+               . /lib/partman/lvm_tools.sh
+               lvm_wipe_disk "$dev" || return 1
+       fi
+
+       cd "$dev" || return 1
+       open_dialog LABEL_TYPES
+       types=$(read_list)
+       close_dialog
+
+       db_subst partman-partitioning/choose_label CHOICES "$types"
+       PRIORITY=critical
+
+       default_type=$(default_disk_label)
+
+       # Use gpt instead of msdos disklabel for disks larger than 2TB
+       if expr "$types" : ".*gpt.*" >/dev/null; then
+               if [ "$default_type" = msdos ] ; then
+                       disksize=$(cat size)
+                       if $(longint_le $(human2longint 2TB) $disksize) ; then
+                               default_type=gpt
+                       fi
+               fi
+       fi
+
+       if expr "$types" : ".*${default_type}.*" >/dev/null; then
+               PRIORITY=low
+       else
+               default_type="msdos" # most widely used
+               PRIORITY=medium
+       fi
+       db_set partman-partitioning/choose_label "$default_type"
+       db_input $PRIORITY partman-partitioning/choose_label || true
+       db_go || exit 1
+       db_get partman-partitioning/choose_label
+
+       chosen_type="$RET"
+
+       if [ "$chosen_type" = sun ]; then
+               db_input critical partman/confirm_write_new_label
+               db_go || exit 0
+               db_get partman/confirm_write_new_label
+               if [ "$RET" = false ]; then
+                       db_reset partman/confirm_write_new_label
+                       exit 1
+               fi
+               db_reset partman/confirm_write_new_label
+       fi
+
+       open_dialog NEW_LABEL "$chosen_type"
+       close_dialog
+
+       if [ "$chosen_type" = sun ]; then
+               # write the partition table to the disk
+               disable_swap
+               open_dialog COMMIT
+               close_dialog
+               sync
+               # reread it from there
+               open_dialog UNDO
+               close_dialog
+               enable_swap
+       fi
+
+       # Different types partition tables support different visuals.  Some
+       # have partition names other don't have, some have extended and
+       # logical partitions, others don't.  Hence we have to regenerate the
+       # list of the visuals
+       rm -f visuals
+
+}
+
 # Unlock a device or partition to allow further modifications
 partman_unlock_unit() {
        local device dev testdev
diff --git a/packages/partman/partman-crypto/crypto_tools.sh 
b/packages/partman/partman-crypto/crypto_tools.sh
index 61f54bc..feecdbd 100644
--- a/packages/partman/partman-crypto/crypto_tools.sh
+++ b/packages/partman/partman-crypto/crypto_tools.sh
@@ -1,5 +1,197 @@
 . /lib/partman/definitions.sh
 
+# Gets the major and minor device numbers of a device passed as $1
+# and puts them in $MAJOR and $MINOR.
+dev_get_major_minor() {
+       local dev stats
+       dev="$1"
+
+       if [ -z "$dev" ]; then
+               return 1
+       fi
+
+       stats=$(ls -al "$dev" | sed -e 's/[[:space:],]\+/ /g')
+       MAJOR=$(echo "$stats" | cut -d' ' -f5)
+       MINOR=$(echo "$stats" | cut -d' ' -f6)
+
+       if [ -z "$MAJOR" ] || [ -z "$MINOR" ]; then
+               return 1
+       fi
+
+       return 0
+}
+
+# Given a lvm device (excluding the /dev/mapper/ part), will gather data on
+# the LVM config, prompt the user and then remove the VG along with all the
+# LV's and PV's which belong to that VG.
+dm_wipe_lvm() {
+       local dev vg pv pvs lv lvs vgtext lvtext pvtext
+       dev="$1"
+
+       # First check that the device exists, it's not an error if it doesn't
+       # since one call to this function can wipe several LV's
+       if [ ! -b "/dev/mapper/$dev" ]; then
+               return 0
+       fi
+
+       if [ ! -e /lib/partman/lvm_tools.sh ]; then
+               return 1
+       fi
+
+       . /lib/partman/lvm_tools.sh
+
+       # We get a device like mainvg-swaplv as $1, let's figure out the VG
+
+       # Make sure that the device includes at least one dash
+        if [ "$(echo -n "$dev" | tr -d -)" = "$dev" ]; then
+                return 1
+       fi
+
+        # Split volume group from logical volume.
+        vg=$(echo ${dev} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')
+        # Reduce padded --'s to -'s
+        vg=$(echo ${vg} | sed -e 's#--#-#g')
+       if [ -z "$vg" ]; then
+               return 1
+       fi
+       pvs=$(vg_list_pvs $vg)
+       lvs=$(vg_list_lvs $vg)
+
+       # Ask for permission to erase LVM volumes
+       vgtext="$vg"
+       pvtext=""
+       for pv in $pvs; do
+               pvtext="${pvtext:+$pvtext, }$pv"
+       done
+       lvtext=""
+       for lv in $lvs; do
+               lvtext="${lvtext:+$lvtext, }$lv"
+       done
+
+       db_subst partman-auto/purge_lvm_from_device VGTARGETS "$vgtext"
+       db_subst partman-auto/purge_lvm_from_device LVTARGETS "$lvtext"
+       db_subst partman-auto/purge_lvm_from_device PVTARGETS "$pvtext"
+       db_input critical partman-auto/purge_lvm_from_device
+       db_go || return 1
+       db_get partman-auto/purge_lvm_from_device
+       if [ "$RET" != "true" ]; then
+               return 1
+       fi
+
+       # Remove the LV's
+       for lv in $lvs; do
+               lv_delete $vg $lv
+       done
+
+       # Remove the VG
+       vg_delete $vg
+
+       # Remove the PV's
+       for pv in $pvs; do
+               pv_delete $pv
+               partman_unlock_unit $pv
+       done
+
+       return 0
+}
+
+# Given a cryptodev (minus the /dev/mapper/ part), will prompt the user and
+# then remove the device.
+dm_wipe_crypto() {
+       local dev
+       dev="$1"
+
+       # Ask for permission to erase crypto volumes
+       db_subst partman-auto/purge_crypto_from_device TARGET "$dev"
+       db_input critical partman-auto/purge_crypto_from_device
+       db_go || return 1
+       db_get partman-auto/purge_crypto_from_device
+       if [ "$RET" != "true" ]; then
+               return 1
+       fi
+
+       dmsetup remove "$dev"
+       return $?
+}
+
+# Given a dm device (minus the /dev/mapper/ part), will recursively remove
+# all devices which depend on it and then the device itself.
+dm_wipe_dev() {
+       local dev deps dep name type
+       dev="$1"
+
+       if [ ! -e "/dev/mapper/$dev" ]; then
+               return 0
+       fi
+
+       dev_get_major_minor "/dev/mapper/$dev" || return 1
+       deps=$(dmsetup deps | grep "($MAJOR, $MINOR)" | cut -d: -f1)
+       for dep in $deps; do
+               if [ ! -e "/dev/mapper/$dep" ]; then
+                       continue
+               fi
+
+               dev_get_major_minor "/dev/mapper/$dep" || return 1
+               name=$(dmsetup info -j$MAJOR -m$MINOR | grep "Name:" | \
+                       cut -d: -f2 | sed -e 's/[[:space:]]//g')
+               if [ -z "$name" ]; then
+                       return 1
+               fi
+
+               dm_wipe_dev "$name" || return 1
+       done
+
+       type=$(dmsetup table | grep "^$dev:" | cut -d' ' -f4)
+       if [ -z "$type" ]; then
+               return 1
+       elif [ "$type" = crypt ]; then
+               dm_wipe_crypto "$dev" || return 1
+       else
+               dm_wipe_lvm "$dev" || return 1
+       fi
+
+       return 0
+}
+
+# Wipes any dm devices from a disk (LVM and/or crypto)
+# Given an argument like /dev/hda, /dev/hda1 and /dev/hda2 are also wiped...
+# Normally you wouldn't want to use this function,
+# but wipe_disk() which will also call this function.
+dm_wipe_disk() {
+       local dev realdev devs check checkdev provide provides restart tmpdev 
tmppart
+       dev="$1"
+
+       if [ -z "$dev" ]; then
+               return 1
+       fi
+
+       realdev=$(mapdevfs "$(cat $dev/device)")
+       devs=$(ls ${realdev}* 2>/dev/null)
+
+       # Given e.g. /dev/hda we check /dev/hda, /dev/hda1, etc...
+       for check in $devs; do
+               checkdev=$(readlink -f "$check")
+               if [ ! -e "$checkdev" ]; then
+                       continue
+               fi
+
+               dev_get_major_minor "$checkdev" || return 1
+
+               provides=$(dmsetup deps | grep "($MAJOR, $MINOR)" | cut -d: -f1)
+
+               if [ -z "$provides" ]; then
+                       continue
+               fi
+
+               for provide in $provides; do
+                       dm_wipe_dev $provide || return 1
+               done
+       done
+
+       update_parted || return 1
+       return 0
+}
+
 dm_dev_is_safe() {
        local maj min dminfo deps
        maj="$1"
diff --git a/packages/partman/partman-crypto/debian/changelog 
b/packages/partman/partman-crypto/debian/changelog
index ebcad60..0dec16f 100644
--- a/packages/partman/partman-crypto/debian/changelog
+++ b/packages/partman/partman-crypto/debian/changelog
@@ -1,7 +1,13 @@
 partman-crypto (23) UNRELEASED; urgency=low
 
+  [ Colin Watson ]
   * Reduce noise from repeated 'debian/rules clean' runs.
 
+  [ Jérémy Bobbio ]
+  * Add dm_wipe_disk and its dependencies to crypto_tools.sh from partman-auto.
+    This function is used by create_new_label() introduced in partman-base
+    (>> 0.110).
+
  -- Colin Watson <[EMAIL PROTECTED]>  Tue, 02 Oct 2007 16:30:15 +0100
 
 partman-crypto (22) unstable; urgency=low
diff --git a/packages/partman/partman-lvm/debian/changelog 
b/packages/partman/partman-lvm/debian/changelog
index 7658cc3..a0f8e15 100644
--- a/packages/partman/partman-lvm/debian/changelog
+++ b/packages/partman/partman-lvm/debian/changelog
@@ -1,3 +1,12 @@
+partman-lvm (56) UNRELEASED; urgency=low
+
+  * Add lvm_wipe_disk() to lvm_tools.sh.  This function is used by
+    create_new_label() introduced in partman-base (>> 110).
+    (Closes: #396023)
+  * Add pv_list_vgs() to lvm_tools.sh.
+
+ -- Jérémy Bobbio <[EMAIL PROTECTED]>  Wed, 24 Oct 2007 19:03:08 +0200
+
 partman-lvm (55) unstable; urgency=low
 
   [ Frans Pop ]
diff --git a/packages/partman/partman-lvm/lvm_tools.sh 
b/packages/partman/partman-lvm/lvm_tools.sh
index 96f33a5..1143255 100644
--- a/packages/partman/partman-lvm/lvm_tools.sh
+++ b/packages/partman/partman-lvm/lvm_tools.sh
@@ -10,6 +10,69 @@ export LVM_SUPPRESS_FD_WARNINGS=1
 #
 ###############################################################################
 
+# Wipes any traces of LVM from a disk
+# Used by create_new_label() if dmsetup is not usable
+lvm_wipe_disk() {
+       local dev realdev vg pvs pv lv tmpdev
+       dev="$1"
+
+       # Check if the device already contains any physical volumes
+       realdev=$(mapdevfs "$(cat $dev/device)")
+       if ! pv_on_device "$realdev"; then
+               return 0
+       fi
+
+        vgs="$(for pv in $(pvs --noheadings --nosuffix -o pv_name |
+                               grep "$realdev"); do
+                       pv_list_vgs "$pv"
+               done | uniq)"
+       pvs="$(for vg in $vgs; do vg_list_pvs $vg; done | uniq)"
+       lvs="$(for vg in $vgs; do vg_list_lvs $vg; done | uniq)"
+
+       # Ask for permission to erase LVM volumes
+       vgtext=""
+       for vg in $vgs; do
+               vgtext="${vgtext:+$vgtext, }$vg"
+       done
+       pvtext=""
+       for pv in $pvs; do
+               pvtext="${pvtext:+$pvtext, }$pv"
+       done
+       lvtext=""
+       for lv in $lvs; do
+               lvtext="${lvtext:+$lvtext, }$lv"
+       done
+
+       db_subst partman-auto/purge_lvm_from_device VGTARGETS "$vgtext"
+       db_subst partman-auto/purge_lvm_from_device LVTARGETS "$lvtext"
+       db_subst partman-auto/purge_lvm_from_device PVTARGETS "$pvtext"
+       db_input critical partman-auto/purge_lvm_from_device
+       db_go || return 1
+       db_get partman-auto/purge_lvm_from_device
+       if [ "$RET" != "true" ]; then
+               return 1
+       fi
+
+       # Remove the LV's
+       for lv in $lvs; do
+               lv_delete $vg $lv
+       done
+
+       # Remove the VG's
+       for vg in $vgs; do
+               vg_delete $vg
+       done
+
+       # Remove the PV's
+       for pv in $pvs; do
+               pv_delete $pv
+               partman_unlock_unit $pv
+       done
+
+       update_parted || return 1
+       return 0
+}
+
 # Convert common terms for disk sizes into something LVM understands.
 #  e.g. "200 gb" -> "200G"
 lvm_size_from_human() {
@@ -243,6 +306,19 @@ pv_list_free() {
        done
 }
 
+# Get all VGs from a PV
+pv_list_vgs() {
+       local line vg pv
+
+       for line in $(lvm_get_info pvs vg_name,pv_name ""); do
+               vg=$(echo "$line" | cut -d':' -f1)
+               pv=$(echo "$line" | cut -d':' -f2)
+               if [ "$pv" = "$1" ]; then
+                       echo "$vg"
+               fi
+       done
+}
+
 # Initialize a PV
 pv_create() {
        local pv
diff --git a/packages/partman/partman-partitioning/debian/changelog 
b/packages/partman/partman-partitioning/debian/changelog
index 768d4ea..7081e1f 100644
--- a/packages/partman/partman-partitioning/debian/changelog
+++ b/packages/partman/partman-partitioning/debian/changelog
@@ -1,3 +1,10 @@
+partman-partitioning (53) UNRELEASED; urgency=low
+
+  * Use create_new_label() from partman-base (>> 110) in
+    storage_device/label/do_option. 
+
+ -- Jérémy Bobbio <[EMAIL PROTECTED]>  Wed, 24 Oct 2007 19:07:23 +0200
+
 partman-partitioning (52) unstable; urgency=low
 
   * Use 'mkdir -p' rather than more awkward test-then-create constructions.
diff --git 
a/packages/partman/partman-partitioning/storage_device/label/do_option 
b/packages/partman/partman-partitioning/storage_device/label/do_option
index 7676b3f..25740d3 100755
--- a/packages/partman/partman-partitioning/storage_device/label/do_option
+++ b/packages/partman/partman-partitioning/storage_device/label/do_option
@@ -14,68 +14,12 @@ if [ "$RET" = false ]; then
        db_reset partman/confirm_new_label
        exit 1
 fi
-db_reset partman/confirm_new_label
-
-open_dialog LABEL_TYPES
-types=$(read_list)
-close_dialog
-
-db_subst partman-partitioning/choose_label CHOICES "$types"
-PRIORITY=critical
-
-default_label=$(default_disk_label)
-
-# Use gpt instead of msdos disklabel for disks larger than 2TB
-if expr "$types" : ".*gpt.*" >/dev/null; then
-       if [ "$default_label" = msdos ] ; then
-               disksize=$(cat size)
-               if $(longint_le $(human2longint 2TB) $disksize) ; then
-                       default_label=gpt
-               fi
-       fi
-fi
-
-if expr "$types" : ".*${default_label}.*" >/dev/null; then
-       db_set partman-partitioning/choose_label "$default_label"
-       PRIORITY=low
-fi
-db_input $PRIORITY partman-partitioning/choose_label || true
-db_go || exit 1
-db_get partman-partitioning/choose_label
+# We do not reset partman/confirm_new_label here as users of "sun" label
+# gets another confirmation screen as changes needs to be done immediately.
 
-chosen_type="$RET"
+create_new_label "$dev"
 
-if [ "$chosen_type" = sun ]; then
-       db_input critical partman/confirm_write_new_label
-       db_go || exit 0
-       db_get partman/confirm_write_new_label
-       if [ "$RET" = false ]; then
-               db_reset partman/confirm_write_new_label
-               exit 1
-       fi
-       db_reset partman/confirm_write_new_label
-fi
-
-open_dialog NEW_LABEL "$chosen_type"
-close_dialog
-
-if [ "$chosen_type" = sun ]; then
-       # write the partition table to the disk
-       disable_swap
-       open_dialog COMMIT
-       close_dialog
-       sync
-       # reread it from there
-       open_dialog UNDO
-       close_dialog
-       enable_swap
-fi
-
-# Different types partition tables support different visuals.  Some
-# have partition names other don't have, some have extended and
-# logical partitions, others don't.  Hence we have to regenerate the
-# list of the visuals
-rm -f visuals
+db_reset partman/confirm_new_label
 
 partitions=''
 open_dialog PARTITIONS
@@ -88,7 +32,11 @@ for id in $partitions; do
        update_partition $dev $id
 done
 
-if [ "$chosen_type" = sun ]; then
+open_dialog GET_LABEL_TYPE
+read_line label_type
+close_dialog
+
+if [ "$label_type" = sun ]; then
        backupdir=../../backup/`basename $dev`
        rm -rf "$backupdir"
        cp -a . "$backupdir"

Attachment: signature.asc
Description: Digital signature

Reply via email to