diff options
Diffstat (limited to 'libfdisk')
-rw-r--r-- | libfdisk/docs/libfdisk-sections.txt | 1 | ||||
-rw-r--r-- | libfdisk/src/Makemodule.am | 1 | ||||
-rw-r--r-- | libfdisk/src/context.c | 57 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 16 | ||||
-rw-r--r-- | libfdisk/src/init.c | 1 | ||||
-rw-r--r-- | libfdisk/src/label.c | 6 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h.in | 8 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.sym | 4 | ||||
-rw-r--r-- | libfdisk/src/partition.c | 137 | ||||
-rw-r--r-- | libfdisk/src/wipe.c | 143 |
10 files changed, 324 insertions, 50 deletions
diff --git a/libfdisk/docs/libfdisk-sections.txt b/libfdisk/docs/libfdisk-sections.txt index dd8df21ef..14d770b7e 100644 --- a/libfdisk/docs/libfdisk-sections.txt +++ b/libfdisk/docs/libfdisk-sections.txt @@ -162,6 +162,7 @@ fdisk_delete_partition fdisk_get_partition fdisk_is_partition_used fdisk_set_partition +fdisk_wipe_partition <SUBSECTION> fdisk_partition fdisk_new_partition diff --git a/libfdisk/src/Makemodule.am b/libfdisk/src/Makemodule.am index bc7f1a378..d7e7f16d8 100644 --- a/libfdisk/src/Makemodule.am +++ b/libfdisk/src/Makemodule.am @@ -21,6 +21,7 @@ libfdisk_la_SOURCES = \ libfdisk/src/iter.c \ libfdisk/src/script.c \ libfdisk/src/version.c \ + libfdisk/src/wipe.c \ \ libfdisk/src/sun.c \ libfdisk/src/sgi.c \ diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 88b9f8afb..26f526a78 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -47,6 +47,8 @@ struct fdisk_context *fdisk_new_context(void) cxt->dev_fd = -1; cxt->refcount = 1; + INIT_LIST_HEAD(&cxt->wipes); + /* * Allocate label specific structs. * @@ -112,6 +114,8 @@ static int init_nested_from_parent(struct fdisk_context *cxt, int isnew) return -ENOMEM; } + INIT_LIST_HEAD(&cxt->wipes); + return 0; } @@ -339,9 +343,15 @@ int fdisk_enable_bootbits_protection(struct fdisk_context *cxt, int enable) * @cxt: fdisk context * @enable: 1 or 0 * - * The library removes all filesystem/RAID signatures before write PT. This is - * no-op if any collision has not been detected by fdisk_assign_device(). See - * fdisk_has_collision(). The default is not wipe a device. + * The library removes all filesystem/RAID signatures before it writes + * partition table. The probing area where it looks for filesystem/RAID is from + * the begin of the disk. The device is wiped by libblkid. + * + * See also fdisk_wipe_partition(). + * + * This is no-op if any collision has not been detected by + * fdisk_assign_device(). See fdisk_has_collision(). The default is not wipe a + * device. * * Returns: 0 on success, < 0 on error. */ @@ -349,7 +359,8 @@ int fdisk_enable_wipe(struct fdisk_context *cxt, int enable) { if (!cxt) return -EINVAL; - cxt->wipe_device = enable ? 1 : 0; + + fdisk_set_wipe_area(cxt, 0, cxt->total_sectors * cxt->sector_size, enable); return 0; } @@ -363,7 +374,10 @@ int fdisk_enable_wipe(struct fdisk_context *cxt, int enable) */ int fdisk_has_wipe(struct fdisk_context *cxt) { - return cxt && cxt->wipe_device; + if (!cxt) + return 0; + + return fdisk_has_wipe_area(cxt, 0, cxt->total_sectors * cxt->sector_size); } @@ -484,6 +498,8 @@ static void reset_context(struct fdisk_context *cxt) cxt->script = NULL; cxt->label = NULL; + + fdisk_free_wipe_areas(cxt); } /* @@ -535,37 +551,6 @@ static int check_collisions(struct fdisk_context *cxt) #endif } -int fdisk_wipe_collisions(struct fdisk_context *cxt) -{ -#ifdef HAVE_LIBBLKID - blkid_probe pr; - int rc; - - assert(cxt); - assert(cxt->dev_fd >= 0); - - DBG(CXT, ul_debugobj(cxt, "wipe: initialize libblkid prober")); - - pr = blkid_new_probe(); - if (!pr) - return -ENOMEM; - rc = blkid_probe_set_device(pr, cxt->dev_fd, 0, 0); - if (rc) - return rc; - - blkid_probe_enable_superblocks(pr, 1); - blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC); - blkid_probe_enable_partitions(pr, 1); - blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC); - - while (blkid_do_probe(pr) == 0) - blkid_do_wipe(pr, FALSE); - - blkid_free_probe(pr); -#endif - return 0; -} - /** * fdisk_assign_device: * @cxt: context diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 85c38492a..6444c3d3e 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -38,6 +38,7 @@ #define LIBFDISK_DEBUG_PARTTYPE (1 << 7) #define LIBFDISK_DEBUG_TAB (1 << 8) #define LIBFDISK_DEBUG_SCRIPT (1 << 9) +#define LIBFDISK_DEBUG_WIPE (1 << 10) #define LIBFDISK_DEBUG_ALL 0xFFFF UL_DEBUG_DECLARE_MASK(libfdisk); @@ -121,6 +122,10 @@ struct fdisk_partition { char *attrs; /* partition flags/attributes converted to string */ struct fdisk_parttype *type; /* partition type */ + char *fstype; /* filesystem type */ + char *fsuuid; /* filesystem uuid */ + char *fslabel; /* filesystem label */ + struct list_head parts; /* list of partitions */ /* extra fields for partition_to_string() */ @@ -143,6 +148,7 @@ struct fdisk_partition { partno_follow_default : 1, /* use default partno */ size_explicit : 1, /* don't align the size */ start_follow_default : 1, /* use default start */ + fs_probed : 1, /* already probed by blkid */ used : 1, /* partition already used */ wholedisk : 1; /* special system partition */ }; @@ -355,10 +361,10 @@ struct fdisk_context { display_in_cyl_units : 1, /* for obscure labels */ display_details : 1, /* expert display mode */ protect_bootbits : 1, /* don't zeroize fll irst sector */ - wipe_device : 1, /* wipe device before write */ listonly : 1; /* list partition, nothing else */ char *collision; /* name of already existing FS/PT */ + struct list_head wipes; /* list of areas to wipe before write */ int sizeunit; /* SIZE fields, FDISK_SIZEUNIT_* */ @@ -389,8 +395,6 @@ struct fdisk_context { struct fdisk_script *script; /* what we want to follow */ }; -int fdisk_wipe_collisions(struct fdisk_context *cxt); - /* context.c */ extern int __fdisk_switch_label(struct fdisk_context *cxt, struct fdisk_label *lb); @@ -455,4 +459,10 @@ extern struct dos_partition *fdisk_dos_get_partition( struct fdisk_context *cxt, size_t i); +/* wipe.c */ +void fdisk_free_wipe_areas(struct fdisk_context *cxt); +int fdisk_set_wipe_area(struct fdisk_context *cxt, uint64_t start, uint64_t size, int enable); +int fdisk_do_wipe(struct fdisk_context *cxt); +int fdisk_has_wipe_area(struct fdisk_context *cxt, uint64_t start, uint64_t size); + #endif /* _LIBFDISK_PRIVATE_H */ diff --git a/libfdisk/src/init.c b/libfdisk/src/init.c index 61acb0a4f..b4de57cd0 100644 --- a/libfdisk/src/init.c +++ b/libfdisk/src/init.c @@ -21,6 +21,7 @@ UL_DEBUG_DEFINE_MASKNAMES(libfdisk) = { "parttype", LIBFDISK_DEBUG_PARTTYPE,"partition type utils" }, { "script", LIBFDISK_DEBUG_SCRIPT, "sfdisk-like scripts" }, { "tab", LIBFDISK_DEBUG_TAB, "table utils"}, + { "wipe", LIBFDISK_DEBUG_WIPE, "wipe area utils" }, { NULL, 0 } }; diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index f2580cf03..ee5ee3e4a 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -304,11 +304,7 @@ int fdisk_write_disklabel(struct fdisk_context *cxt) if (!cxt->label->op->write) return -ENOSYS; - if (cxt->collision && cxt->wipe_device) { - int rc = fdisk_wipe_collisions(cxt); - if (rc) - return rc; - } + fdisk_do_wipe(cxt); return cxt->label->op->write(cxt); } diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index 7bcacd6da..6bd3a1e56 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -285,6 +285,10 @@ enum fdisk_fieldtype { FDISK_FIELD_SADDR, /* Start-C/H/S (MBR) */ FDISK_FIELD_UUID, /* partition UUID (GPT) */ + FDISK_FIELD_FSUUID, + FDISK_FIELD_FSLABEL, + FDISK_FIELD_FSTYPE, + FDISK_NFIELDS /* must be last */ }; @@ -321,9 +325,10 @@ extern int fdisk_get_partition(struct fdisk_context *cxt, size_t partno, struct extern int fdisk_set_partition(struct fdisk_context *cxt, size_t partno, struct fdisk_partition *pa); extern int fdisk_add_partition(struct fdisk_context *cxt, struct fdisk_partition *pa, size_t *partno); extern int fdisk_delete_partition(struct fdisk_context *cxt, size_t partno); - extern int fdisk_delete_all_partitions(struct fdisk_context *cxt); +extern int fdisk_wipe_partition(struct fdisk_context *cxt, size_t partno, int enable); + extern int fdisk_set_partition_type(struct fdisk_context *cxt, size_t partnum, struct fdisk_parttype *t); @@ -389,6 +394,7 @@ size_t fdisk_partition_get_partno(struct fdisk_partition *pa); int fdisk_partition_has_partno(struct fdisk_partition *pa); int fdisk_partition_cmp_partno(struct fdisk_partition *a, struct fdisk_partition *b); + int fdisk_partition_partno_follow_default(struct fdisk_partition *pa, int enable); extern int fdisk_partition_set_type(struct fdisk_partition *pa, struct fdisk_parttype *type); diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym index 6a412bc20..c5aeac68e 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -259,3 +259,7 @@ FDISK_2.28 { fdisk_get_collision; fdisk_has_wipe; } FDISK_2.27; + +FDISK_2.29 { + fdisk_wipe_partition; +} FDISK_2.28; diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c index 5e41eed0d..4fbd1e468 100644 --- a/libfdisk/src/partition.c +++ b/libfdisk/src/partition.c @@ -2,6 +2,10 @@ #include "c.h" #include "strutils.h" +#ifdef HAVE_LIBBLKID +# include <blkid.h> +#endif + #include "fdiskP.h" /** @@ -63,6 +67,9 @@ void fdisk_reset_partition(struct fdisk_partition *pa) free(pa->name); free(pa->uuid); free(pa->attrs); + free(pa->fstype); + free(pa->fsuuid); + free(pa->fslabel); memset(pa, 0, sizeof(*pa)); pa->refcount = ref; @@ -85,6 +92,13 @@ static struct fdisk_partition *__copy_partition(struct fdisk_partition *o) n->uuid = strdup(o->uuid); if (o->attrs) n->attrs = strdup(o->attrs); + if (o->fstype) + n->fstype = strdup(o->fstype); + if (o->fsuuid) + n->fsuuid = strdup(o->fsuuid); + if (o->fslabel) + n->fslabel = strdup(o->fslabel); + return n; } @@ -127,7 +141,7 @@ void fdisk_unref_partition(struct fdisk_partition *pa) * @off: offset in sectors, maximal is UINT64_MAX-1 * * Note that zero is valid offset too. Use fdisk_partition_unset_start() to - * undefine the offset. + * undefine the offset. * * Returns: 0 on success, <0 on error. */ @@ -138,6 +152,7 @@ int fdisk_partition_set_start(struct fdisk_partition *pa, fdisk_sector_t off) if (FDISK_IS_UNDEF(off)) return -ERANGE; pa->start = off; + pa->fs_probed = 0; return 0; } @@ -154,6 +169,7 @@ int fdisk_partition_unset_start(struct fdisk_partition *pa) if (!pa) return -EINVAL; FDISK_INIT_UNDEF(pa->start); + pa->fs_probed = 0; return 0; } @@ -259,6 +275,7 @@ int fdisk_partition_set_size(struct fdisk_partition *pa, fdisk_sector_t sz) if (FDISK_IS_UNDEF(sz)) return -ERANGE; pa->size = sz; + pa->fs_probed = 0; return 0; } @@ -275,6 +292,7 @@ int fdisk_partition_unset_size(struct fdisk_partition *pa) if (!pa) return -EINVAL; FDISK_INIT_UNDEF(pa->size); + pa->fs_probed = 0; return 0; } @@ -724,6 +742,60 @@ int fdisk_partition_next_partno( return 0; } +static int probe_partition_content(struct fdisk_context *cxt, struct fdisk_partition *pa) +{ + int rc = 1; /* nothing */ + + DBG(PART, ul_debugobj(pa, "start probe #%zu partition [cxt %p] >>>", pa->partno, cxt)); + + /* zeroize the current setting */ + strdup_to_struct_member(pa, fstype, NULL); + strdup_to_struct_member(pa, fsuuid, NULL); + strdup_to_struct_member(pa, fslabel, NULL); + + if (!fdisk_partition_has_start(pa) || + !fdisk_partition_has_size(pa)) + goto done; + +#ifdef HAVE_LIBBLKID + else { + uintmax_t start, size; + + blkid_probe pr = blkid_new_probe(); + if (!pr) + goto done; + + DBG(PART, ul_debugobj(pa, "blkid prober: %p", pr)); + + start = fdisk_partition_get_start(pa) * fdisk_get_sector_size(cxt); + size = fdisk_partition_get_size(pa) * fdisk_get_sector_size(cxt); + + if (blkid_probe_set_device(pr, cxt->dev_fd, start, size) == 0 + && blkid_do_fullprobe(pr) == 0) { + + const char *data; + rc = 0; + + if (!blkid_probe_lookup_value(pr, "TYPE", &data, NULL)) + rc = strdup_to_struct_member(pa, fstype, data); + + if (!rc && !blkid_probe_lookup_value(pr, "LABEL", &data, NULL)) + rc = strdup_to_struct_member(pa, fslabel, data); + + if (!rc && !blkid_probe_lookup_value(pr, "UUID", &data, NULL)) + rc = strdup_to_struct_member(pa, fsuuid, data); + } + + blkid_free_probe(pr); + pa->fs_probed = 1; + } +#endif /* HAVE_LIBBLKID */ + +done: + DBG(PART, ul_debugobj(pa, "<<< end probe #%zu partition[cxt %p, rc=%d]", pa->partno, cxt, rc)); + return rc; +} + /** * fdisk_partition_to_string: * @pa: partition @@ -859,6 +931,18 @@ int fdisk_partition_to_string(struct fdisk_partition *pa, case FDISK_FIELD_EADDR: p = pa->end_chs && *pa->end_chs? strdup(pa->end_chs) : NULL; break; + case FDISK_FIELD_FSUUID: + if (pa->fs_probed || probe_partition_content(cxt, pa) == 0) + p = pa->fsuuid && *pa->fsuuid ? strdup(pa->fsuuid) : NULL; + break; + case FDISK_FIELD_FSLABEL: + if (pa->fs_probed || probe_partition_content(cxt, pa) == 0) + p = pa->fslabel && *pa->fslabel ? strdup(pa->fslabel) : NULL; + break; + case FDISK_FIELD_FSTYPE: + if (pa->fs_probed || probe_partition_content(cxt, pa) == 0) + p = pa->fstype && *pa->fstype ? strdup(pa->fstype) : NULL; + break; default: return -EINVAL; } @@ -876,6 +960,7 @@ int fdisk_partition_to_string(struct fdisk_partition *pa, return rc; } + /** * fdisk_get_partition: * @cxt: context @@ -1140,14 +1225,16 @@ erange: int fdisk_set_partition(struct fdisk_context *cxt, size_t partno, struct fdisk_partition *pa) { - struct fdisk_partition *xpa = pa; - int rc; + struct fdisk_partition *xpa = pa, *tmp = NULL; + int rc, wipe = 0; if (!cxt || !cxt->label || !pa) return -EINVAL; if (!cxt->label->op->set_part) return -ENOSYS; + pa->fs_probed = 0; + if (pa->resize || fdisk_partition_has_start(pa) || fdisk_partition_has_size(pa)) { xpa = __copy_partition(pa); xpa->movestart = 0; @@ -1166,7 +1253,19 @@ int fdisk_set_partition(struct fdisk_context *cxt, size_t partno, (uintmax_t) fdisk_partition_get_end(xpa), (uintmax_t) fdisk_partition_get_size(xpa))); + /* disable wipe for old offset/size setting */ + if (fdisk_get_partition(cxt, partno, &tmp) == 0 && tmp) { + wipe = fdisk_set_wipe_area(cxt, fdisk_partition_get_start(tmp), + fdisk_partition_get_size(tmp), FALSE); + fdisk_unref_partition(tmp); + } + + /* call label driver */ rc = cxt->label->op->set_part(cxt, partno, xpa); + + /* enable wipe for new offset/size */ + if (!rc && wipe) + fdisk_wipe_partition(cxt, partno, TRUE); done: DBG(CXT, ul_debugobj(cxt, "set_partition() rc=%d", rc)); if (xpa != pa) @@ -1174,6 +1273,31 @@ done: return rc; } +/** + * fdisk_wipe_partition: + * @cxt: fdisk context + * @partno: partition number + * @enable: 0 or 1 + * + * Enable/disable filesystems/RAIDs wiping in area defined by partition start and size. + * + * Returns: <0 in case of error, 0 on success + */ +int fdisk_wipe_partition(struct fdisk_context *cxt, size_t partno, int enable) +{ + struct fdisk_partition *pa = NULL; + int rc; + + rc = fdisk_get_partition(cxt, partno, &pa); + if (rc) + return rc; + + rc = fdisk_set_wipe_area(cxt, fdisk_partition_get_start(pa), + fdisk_partition_get_size(pa), enable); + fdisk_unref_partition(pa); + return rc < 0 ? rc : 0; +} + /** * fdisk_add_partition: @@ -1201,7 +1325,8 @@ int fdisk_add_partition(struct fdisk_context *cxt, if (fdisk_missing_geometry(cxt)) return -EINVAL; - if (pa) + if (pa) { + pa->fs_probed = 0; DBG(CXT, ul_debugobj(cxt, "adding new partition %p (start=%ju, end=%ju, size=%ju, " "defaults(start=%s, end=%s, partno=%s)", pa, @@ -1211,7 +1336,7 @@ int fdisk_add_partition(struct fdisk_context *cxt, pa->start_follow_default ? "yes" : "no", pa->end_follow_default ? "yes" : "no", pa->partno_follow_default ? "yes" : "no")); - else + } else DBG(CXT, ul_debugobj(cxt, "adding partition")); rc = cxt->label->op->add_part(cxt, pa, partno); @@ -1236,6 +1361,8 @@ int fdisk_delete_partition(struct fdisk_context *cxt, size_t partno) if (!cxt->label->op->del_part) return -ENOSYS; + fdisk_wipe_partition(cxt, partno, 0); + DBG(CXT, ul_debugobj(cxt, "deleting %s partition number %zd", cxt->label->name, partno)); return cxt->label->op->del_part(cxt, partno); diff --git a/libfdisk/src/wipe.c b/libfdisk/src/wipe.c new file mode 100644 index 000000000..2c91da57f --- /dev/null +++ b/libfdisk/src/wipe.c @@ -0,0 +1,143 @@ +#include "c.h" +#include "strutils.h" + +#ifdef HAVE_LIBBLKID +# include <blkid.h> +#endif + +#include "fdiskP.h" + +struct fdisk_wipe { + struct list_head wipes; + uint64_t start; /* sectors */ + uint64_t size; /* sectors */ +}; + +static struct fdisk_wipe *fdisk_get_wipe_area( + struct fdisk_context *cxt, + uint64_t start, + uint64_t size) +{ + struct list_head *p; + + if (cxt == NULL || list_empty(&cxt->wipes)) + return NULL; + + list_for_each(p, &cxt->wipes) { + struct fdisk_wipe *wp = list_entry(p, struct fdisk_wipe, wipes); + if (wp->start == start && wp->size == size) + return wp; + } + return NULL; +} + +void fdisk_free_wipe_areas(struct fdisk_context *cxt) +{ + while (!list_empty(&cxt->wipes)) { + struct fdisk_wipe *wp = list_entry(cxt->wipes.next, + struct fdisk_wipe, wipes); + DBG(WIPE, ul_debugobj(wp, "free [start=%ju, size=%ju]", + (uintmax_t) wp->start, (uintmax_t) wp->size)); + list_del(&wp->wipes); + free(wp); + } +} + +int fdisk_has_wipe_area(struct fdisk_context *cxt, + uint64_t start, + uint64_t size) +{ + return fdisk_get_wipe_area(cxt, start, size) != NULL; +} + +/* Add/remove new wiping area + * + * Returns: <0 on error, or old area setting (1: enabled, 0: disabled) + */ +int fdisk_set_wipe_area(struct fdisk_context *cxt, + uint64_t start, + uint64_t size, + int enable) +{ + struct fdisk_wipe *wp; + + if (FDISK_IS_UNDEF(start) || FDISK_IS_UNDEF(size)) + return -EINVAL; + + wp = fdisk_get_wipe_area(cxt, start, size); + + /* disable */ + if (!enable) { + if (wp) { + DBG(WIPE, ul_debugobj(wp, "disable [start=%ju, size=%ju]", + (uintmax_t) start, (uintmax_t) size)); + list_del(&wp->wipes); + free(wp); + return 1; + } + return 0; + } + + /* enable */ + if (wp) + return 1; /* already enabled */ + + wp = calloc(1, sizeof(*wp)); + if (!wp) + return -ENOMEM; + + DBG(WIPE, ul_debugobj(wp, "enable [start=%ju, size=%ju]", + (uintmax_t) start, (uintmax_t) size)); + + INIT_LIST_HEAD(&wp->wipes); + wp->start = start; + wp->size = size; + list_add_tail(&wp->wipes, &cxt->wipes); + + return 0; +} + +int fdisk_do_wipe(struct fdisk_context *cxt) +{ +#ifdef HAVE_LIBBLKID + struct list_head *p; + blkid_probe pr; + int rc; + + assert(cxt); + assert(cxt->dev_fd >= 0); + + if (list_empty(&cxt->wipes)) + return 0; + + pr = blkid_new_probe(); + if (!pr) + return -ENOMEM; + + list_for_each(p, &cxt->wipes) { + struct fdisk_wipe *wp = list_entry(p, struct fdisk_wipe, wipes); + blkid_loff_t start = (blkid_loff_t) wp->start * cxt->sector_size, + size = (blkid_loff_t) wp->size * cxt->sector_size; + + DBG(WIPE, ul_debugobj(wp, "initialize libblkid prober [start=%ju, size=%ju]", + (uintmax_t) start, (uintmax_t) size)); + + rc = blkid_probe_set_device(pr, cxt->dev_fd, start, size); + if (rc) + return rc; + + blkid_probe_enable_superblocks(pr, 1); + blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC); + blkid_probe_enable_partitions(pr, 1); + blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC); + + while (blkid_do_probe(pr) == 0) { + DBG(WIPE, ul_debugobj(wp, " wiping...")); + blkid_do_wipe(pr, FALSE); + } + } + + blkid_free_probe(pr); +#endif + return 0; +} |