Skip to content

Commit

Permalink
libfdisk: add fdisk_wipe_partition()
Browse files Browse the repository at this point in the history
Now libfdisk provides functionality wipe disk device only ([s]fdisk
option --wipe).

This patch allows to probe for filesystems/RAIDs on newly created
partitions.  It means we can remove signatures before the partition
node (device) is created. This reduces udev events and it's
unnecessary to call wipefs for all partitions.  For example

  sfdisk --wipe=always --wipe-partitions=always /dev/sda <<<
  ...
  EOF

is a elegant way how to create new disk layout without any obsolete
filesystems/RAIDs.

Signed-off-by: Karel Zak <kzak@redhat.com>
  • Loading branch information
karelzak committed May 4, 2016
1 parent 55ad13c commit 131e38a
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 50 deletions.
1 change: 1 addition & 0 deletions libfdisk/docs/libfdisk-sections.txt
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions libfdisk/src/Makemodule.am
Expand Up @@ -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 \
Expand Down
57 changes: 21 additions & 36 deletions libfdisk/src/context.c
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -339,17 +343,24 @@ 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.
*/
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;
}

Expand All @@ -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);
}


Expand Down Expand Up @@ -484,6 +498,8 @@ static void reset_context(struct fdisk_context *cxt)
cxt->script = NULL;

cxt->label = NULL;

fdisk_free_wipe_areas(cxt);
}

/*
Expand Down Expand Up @@ -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
Expand Down
16 changes: 13 additions & 3 deletions libfdisk/src/fdiskP.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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() */
Expand All @@ -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 */
};
Expand Down Expand Up @@ -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_* */

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
1 change: 1 addition & 0 deletions libfdisk/src/init.c
Expand Up @@ -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 }
};

Expand Down
6 changes: 1 addition & 5 deletions libfdisk/src/label.c
Expand Up @@ -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);
}

Expand Down
8 changes: 7 additions & 1 deletion libfdisk/src/libfdisk.h.in
Expand Up @@ -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 */
};

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions libfdisk/src/libfdisk.sym
Expand Up @@ -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;

0 comments on commit 131e38a

Please sign in to comment.