Merge lp:~yuningdodo/ubuntu/trusty/util-linux/util-linux.backport-wipefs-partition-table-erasing-support into lp:ubuntu/trusty-updates/util-linux

Proposed by Yu Ning
Status: Needs review
Proposed branch: lp:~yuningdodo/ubuntu/trusty/util-linux/util-linux.backport-wipefs-partition-table-erasing-support
Merge into: lp:ubuntu/trusty-updates/util-linux
Diff against target: 710 lines (+338/-140)
11 files modified
debian/changelog (+17/-0)
libblkid/src/blkid.h.in (+3/-0)
libblkid/src/blkid.sym (+8/-0)
libblkid/src/blkidP.h (+2/-0)
libblkid/src/partitions/gpt.c (+9/-0)
libblkid/src/partitions/partitions.c (+12/-4)
libblkid/src/partitions/ultrix.c (+10/-0)
libblkid/src/probe.c (+133/-0)
libblkid/src/superblocks/superblocks.c (+0/-15)
libblkid/src/superblocks/superblocks.h (+0/-2)
misc-utils/wipefs.c (+144/-119)
To merge this branch: bzr merge lp:~yuningdodo/ubuntu/trusty/util-linux/util-linux.backport-wipefs-partition-table-erasing-support
Reviewer Review Type Date Requested Status
Mathieu Trudel-Lapierre Needs Information
Review via email: mp+237898@code.launchpad.net

Description of the change

  * wipefs: backport partition table erasing support from
    git://git.debian.org/git/collab-maint/pkg-util-linux.git
    - 6611a3dd783006fd8c6b924a76c4820287278d36
      wipefs: improve -a, use blkid_do_wipe()
    - 2b89be6c802bdbdf6830dbd060c96e33f179b135
      libblkid: add blkid_do_wipe()
    - 476b508e043b6b4c71d84b4f2fdeeffa68c204b3
      libblkid: add BLKID_PARTS_MAGIC to blkid_do_wipe() docs
    - 3c83b3b22f33fc7b17b504158e4a4db7b567bbe8
      libblkid: add BLKID_PARTS_MAGIC
    - 44765fdd841fb1369cf68f360131ed076f3a2771
      libblkid: export info about PT magic strings

To post a comment you must log in.
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote :

I think this was workarounded in usb-creator instead, am I wrong? With the reasoning that this new feature backport would be a little too heavy in a core part like util-linux.

The latest usb-creator in 14.04 LTS is this https://launchpad.net/ubuntu/+source/usb-creator/0.2.56.3

So I'd mark this as rejected, please re-open if you think this should still be targeted towards trusty.

Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote :

To be noted though for any core dev considering this, this version of the backport is much less invasive than the previous one https://code.launchpad.net/~yuningdodo/ubuntu/trusty/util-linux/util-linux.backport-utopic-2.25-8ubuntu1/+merge/232848

Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote :

Hmm, reopening. As noted on the bug, the disk utility program would still need this.

Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

How does this affect https://launchpad.net/bugs/1046665? Have you also tested that this bug isn't regressed by these cherry-picks? What packages might be broken by the changes to libblkid?

It also seems to me like some of these commits probably aren't strictly required to support the changes to wipefs, since that's what is at stake here. Do you have a deep enough understanding of the changes here to know exactly why each of these commits are required? It looks to me like only a subset of these changes might be required to fix the targetted bug, but I only looked really quickly.

For example, it seems to me like the fix should work without the last three commits, and just the addition of blkid_do_wipe in libblkid/src/probe.c from 2b89be6c802bdbdf6830dbd060c96e33f179b135.

review: Needs Information
Revision history for this message
Yu Ning (yuningdodo) wrote :

Thanks for the review.

I checked the ubuntu branch, lp:ubuntu/util-linux, bug #1046665 was firstly fixed in rev90 by retrying the operation several times. Later in rev110 the code was entirely merged with debian experimental, and the previous retry was now implemented by calling blkid_do_probe() multiple times until it returns false. What I proposed to do for the trusty branch is similar, first retire the previous retrying logic then introduce the new implementation, so I believe it will not regress bug #1046665. About libblkid, here is a summary of what have been changed:

* new flag: BLKID_PARTS_MAGIC.
* new public method blkid_probe_wipe().
* declaration of blkid_probe_set_magic() is moved to libblkid/src/blkid.h from libblkid/src/superblocks/superblocks.h, so it will become a public method.

Besides these API changes, there are also some internal changes. I think they won't break the API backward compatibility of libblkid.

About the picked patches, I can't say I have a deep enough understanding about the patches, actually I picked them based on the test results of this simple testcase:

dd if=/dev/zero of=data bs=1M count=4
parted data --script -- mklabel msdos
parted data --script -- mkpart primary fat16 0 -0
wipefs -a data # it's expected to output "2 bytes were erased at offset 0x000001fe (dos): 55 aa"

With the first two patches it's not enough to erase the "55aa" signature. In fact the key patch is the last one, 44765fdd841fb1369cf68f360131ed076f3a2771, the other 4 patches are just its dependences. If we want to only pick the key patch, we may have to modify it a lot and causes future conflicts when other patches are being backported.

Revision history for this message
Amr Ibrahim (amribrahim1987) wrote :

Any updates on this?

Unmerged revisions

114. By Yu Ning

44765fdd841fb1369cf68f360131ed076f3a2771 libblkid: export info about PT magic strings

113. By Yu Ning

3c83b3b22f33fc7b17b504158e4a4db7b567bbe8 libblkid: add BLKID_PARTS_MAGIC

112. By Yu Ning

476b508e043b6b4c71d84b4f2fdeeffa68c204b3 libblkid: add BLKID_PARTS_MAGIC to blkid_do_wipe() docs

111. By Yu Ning

2b89be6c802bdbdf6830dbd060c96e33f179b135 libblkid: add blkid_do_wipe()

110. By Yu Ning

* wipefs: backport partition table erasing support from
  git://git.debian.org/git/collab-maint/pkg-util-linux.git
  - 6611a3dd783006fd8c6b924a76c4820287278d36
    wipefs: improve -a, use blkid_do_wipe()

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-06-02 13:36:20 +0000
3+++ debian/changelog 2014-10-10 06:30:46 +0000
4@@ -1,3 +1,20 @@
5+util-linux (2.20.1-5.1ubuntu20.1~test1) UNRELEASED; urgency=medium
6+
7+ * wipefs: backport partition table erasing support from
8+ git://git.debian.org/git/collab-maint/pkg-util-linux.git
9+ - 6611a3dd783006fd8c6b924a76c4820287278d36
10+ wipefs: improve -a, use blkid_do_wipe()
11+ - 2b89be6c802bdbdf6830dbd060c96e33f179b135
12+ libblkid: add blkid_do_wipe()
13+ - 476b508e043b6b4c71d84b4f2fdeeffa68c204b3
14+ libblkid: add BLKID_PARTS_MAGIC to blkid_do_wipe() docs
15+ - 3c83b3b22f33fc7b17b504158e4a4db7b567bbe8
16+ libblkid: add BLKID_PARTS_MAGIC
17+ - 44765fdd841fb1369cf68f360131ed076f3a2771
18+ libblkid: export info about PT magic strings
19+
20+ -- Yu Ning <ning.yu@canonical.com> Fri, 10 Oct 2014 14:16:52 +0800
21+
22 util-linux (2.20.1-5.1ubuntu20.1) trusty-proposed; urgency=medium
23
24 * fstrim-all: Fix typo that made unwanted stderr output from hdparm appear.
25
26=== modified file 'libblkid/src/blkid.h.in'
27--- libblkid/src/blkid.h.in 2011-11-03 15:38:23 +0000
28+++ libblkid/src/blkid.h.in 2014-10-10 06:30:46 +0000
29@@ -278,6 +278,7 @@
30 /* partitions probing flags */
31 #define BLKID_PARTS_FORCE_GPT (1 << 1)
32 #define BLKID_PARTS_ENTRY_DETAILS (1 << 2)
33+#define BLKID_PARTS_MAGIC (1 << 3)
34 extern int blkid_probe_set_partitions_flags(blkid_probe pr, int flags);
35
36 /* binary interface */
37@@ -319,6 +320,8 @@
38 const char **data, size_t *len);
39 extern int blkid_probe_has_value(blkid_probe pr, const char *name);
40
41+extern int blkid_do_wipe(blkid_probe pr, int dryrun);
42+
43 /*
44 * Deprecated functions/macros
45 */
46
47=== modified file 'libblkid/src/blkid.sym'
48--- libblkid/src/blkid.sym 2011-11-03 15:38:23 +0000
49+++ libblkid/src/blkid.sym 2014-10-10 06:30:46 +0000
50@@ -140,3 +140,11 @@
51 blkid_superblocks_get_name;
52 } BLKID_2.18;
53
54+/*
55+ * symbols since util-linux 2.21
56+ */
57+BLKID_2.21 {
58+global:
59+ blkid_do_wipe;
60+} BLKID_2.20;
61+
62
63=== modified file 'libblkid/src/blkidP.h'
64--- libblkid/src/blkidP.h 2011-11-03 15:38:23 +0000
65+++ libblkid/src/blkidP.h 2014-10-10 06:30:46 +0000
66@@ -426,6 +426,8 @@
67 const char *fmt, va_list ap);
68 extern int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
69 const char *fmt, ...);
70+extern int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
71+ size_t len, unsigned char *magic);
72
73 extern void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len);
74 extern size_t blkid_rtrim_whitespace(unsigned char *str);
75
76=== modified file 'libblkid/src/partitions/gpt.c'
77--- libblkid/src/partitions/gpt.c 2011-11-03 15:38:23 +0000
78+++ libblkid/src/partitions/gpt.c 2014-10-10 06:30:46 +0000
79@@ -26,6 +26,7 @@
80
81 /* Signature - “EFI PART” */
82 #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
83+#define GPT_HEADER_SIGNATURE_STR "EFI PART"
84
85 /* basic types */
86 typedef uint16_t efi_char16_t;
87@@ -326,6 +327,14 @@
88 if (!tab)
89 goto err;
90
91+ blkid_probe_set_magic(pr, lba << 9,
92+ sizeof(GPT_HEADER_SIGNATURE_STR) - 1,
93+ (unsigned char *) GPT_HEADER_SIGNATURE_STR);
94+
95+ blkid_probe_set_magic(pr, lba << 9,
96+ sizeof(GPT_HEADER_SIGNATURE_STR) - 1,
97+ (unsigned char *) GPT_HEADER_SIGNATURE_STR);
98+
99 ssf = blkid_probe_get_sectorsize(pr) / 512;
100
101 fu = le64_to_cpu(h->first_usable_lba);
102
103=== modified file 'libblkid/src/partitions/partitions.c'
104--- libblkid/src/partitions/partitions.c 2011-11-03 15:38:23 +0000
105+++ libblkid/src/partitions/partitions.c 2014-10-10 06:30:46 +0000
106@@ -530,15 +530,17 @@
107 return 1;
108 }
109
110-static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id)
111+static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id,
112+ struct blkid_chain *chn)
113 {
114 const struct blkid_idmag *mag;
115+ blkid_loff_t off;
116 int rc = 1; /* = nothing detected */
117
118 if (pr->size <= 0 || (id->minsz && id->minsz > pr->size))
119 goto nothing; /* the device is too small */
120
121- if (blkid_probe_get_idmag(pr, id, NULL, &mag))
122+ if (blkid_probe_get_idmag(pr, id, &off, &mag))
123 goto nothing;
124
125 /* final check by probing function */
126@@ -549,9 +551,15 @@
127 if (rc == -1) {
128 /* reset after error */
129 reset_partlist(blkid_probe_get_partlist(pr));
130+ if (chn && !chn->binary)
131+ blkid_probe_chain_reset_vals(pr, chn);
132 DBG(DEBUG_LOWPROBE, printf(
133 "%s probefunc failed\n", id->name));
134 }
135+ if (rc == 0 && mag && chn && !chn->binary)
136+ blkid_probe_set_magic(pr, off, mag->len,
137+ (unsigned char *) mag->magic);
138+
139 DBG(DEBUG_LOWPROBE, printf(
140 "%s: <--- (rc = %d)\n", id->name, rc));
141 }
142@@ -594,7 +602,7 @@
143 continue;
144
145 /* apply checks from idinfo */
146- if (idinfo_probe(pr, idinfos[i]) != 0)
147+ if (idinfo_probe(pr, idinfos[i], chn) != 0)
148 continue;
149
150 name = idinfos[i]->name;
151@@ -678,7 +686,7 @@
152
153 blkid_probe_set_partlist(prc, ls);
154
155- rc = idinfo_probe(prc, id);
156+ rc = idinfo_probe(prc, id, blkid_probe_get_chain(pr));
157
158 blkid_probe_set_partlist(prc, NULL);
159 blkid_partlist_set_parent(ls, NULL);
160
161=== modified file 'libblkid/src/partitions/ultrix.c'
162--- libblkid/src/partitions/ultrix.c 2011-11-03 15:38:23 +0000
163+++ libblkid/src/partitions/ultrix.c 2014-10-10 06:30:46 +0000
164@@ -15,7 +15,9 @@
165 #include "partitions.h"
166
167 #define ULTRIX_MAXPARTITIONS 8
168+
169 #define ULTRIX_MAGIC 0x032957
170+#define ULTRIX_MAGIC_STR "\x02\x29\x57"
171
172 /* sector with partition table */
173 #define ULTRIX_SECTOR ((16384 - sizeof(struct ultrix_disklabel)) >> 9)
174@@ -62,6 +64,14 @@
175 if (!tab)
176 goto err;
177
178+ blkid_probe_set_magic(pr, (ULTRIX_SECTOR << 9) + ULTRIX_OFFSET,
179+ sizeof(ULTRIX_MAGIC_STR) - 1,
180+ (unsigned char *) ULTRIX_MAGIC_STR);
181+
182+ blkid_probe_set_magic(pr, (ULTRIX_SECTOR << 9) + ULTRIX_OFFSET,
183+ sizeof(ULTRIX_MAGIC_STR) - 1,
184+ (unsigned char *) ULTRIX_MAGIC_STR);
185+
186 for (i = 0; i < ULTRIX_MAXPARTITIONS; i++) {
187 if (!l->pt_part[i].pi_nblocks)
188 blkid_partlist_increment_partno(ls);
189
190=== modified file 'libblkid/src/probe.c'
191--- libblkid/src/probe.c 2011-11-03 15:38:23 +0000
192+++ libblkid/src/probe.c 2014-10-10 06:30:46 +0000
193@@ -109,6 +109,7 @@
194 #endif
195
196 #include "blkidP.h"
197+#include "writeall.h"
198
199 /* chains */
200 extern const struct blkid_chaindrv superblocks_drv;
201@@ -914,6 +915,105 @@
202 }
203
204 /**
205+ * blkid_do_wipe:
206+ * @pr: prober
207+ * @dryrun: if TRUE then don't touch the device.
208+ *
209+ * This function erases the current signature detected by @pr. The @pr has to
210+ * be open in O_RDWR mode, BLKID_SUBLKS_MAGIC or/and BLKID_PARTS_MAGIC flags
211+ * has to be enabled.
212+ *
213+ * After successful signature removing the @pr prober will be moved one step
214+ * back and the next blkid_do_probe() call will again call previously called
215+ * probing function.
216+ *
217+ * <example>
218+ * <title>wipe all filesystems or raids from the device</title>
219+ * <programlisting>
220+ * fd = open(devname, O_RDWR);
221+ * blkid_probe_set_device(pr, fd, 0, 0);
222+ *
223+ * blkid_probe_enable_superblocks(pr, 1);
224+ * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
225+ *
226+ * while (blkid_do_probe(pr) == 0)
227+ * blkid_do_wipe(pr, FALSE);
228+ * </programlisting>
229+ * </example>
230+ *
231+ * Returns: 0 on success, 1 when probing is done and -1 in case of error.
232+ */
233+int blkid_do_wipe(blkid_probe pr, int dryrun)
234+{
235+ const char *off = NULL;
236+ size_t len = 0;
237+ loff_t offset, l;
238+ char buf[BUFSIZ];
239+ int fd, rc;
240+ struct blkid_chain *chn;
241+
242+ if (!pr)
243+ return -1;
244+
245+ chn = pr->cur_chain;
246+ if (!chn)
247+ return -1;
248+
249+ switch (chn->driver->id) {
250+ case BLKID_CHAIN_SUBLKS:
251+ rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
252+ if (!rc)
253+ rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
254+ break;
255+ case BLKID_CHAIN_PARTS:
256+ rc = blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &off, NULL);
257+ if (!rc)
258+ rc = blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
259+ break;
260+ default:
261+ return 0;
262+ }
263+
264+ if (rc || len == 0 || off == NULL)
265+ return 0;
266+
267+ offset = strtoll(off, NULL, 10);
268+ fd = blkid_probe_get_fd(pr);
269+ if (fd < 0)
270+ return -1;
271+
272+ if (len > sizeof(buf))
273+ len = sizeof(buf);
274+
275+ DBG(DEBUG_LOWPROBE, printf(
276+ "wiping [offset=0x%jx, len=%zd, chain=%s, idx=%d, dryrun=%s]\n",
277+ offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not"));
278+
279+ l = lseek(fd, offset, SEEK_SET);
280+ if (l == (off_t) -1)
281+ return -1;
282+
283+ memset(buf, 0, len);
284+
285+ if (!dryrun && len) {
286+ if (write_all(fd, buf, len))
287+ return -1;
288+ fsync(fd);
289+
290+ blkid_probe_reset_buffer(pr);
291+
292+ if (chn->idx >= 0) {
293+ chn->idx--;
294+ DBG(DEBUG_LOWPROBE,
295+ printf("wipe: moving %s chain index to %d\n",
296+ chn->driver->name,
297+ chn->idx));
298+ }
299+ }
300+ return 0;
301+}
302+
303+/**
304 * blkid_do_safeprobe:
305 * @pr: prober
306 *
307@@ -1124,6 +1224,39 @@
308 return rc;
309 }
310
311+int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
312+ size_t len, unsigned char *magic)
313+{
314+ int rc = 0;
315+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
316+
317+ if (!chn || !magic || !len || chn->binary)
318+ return 0;
319+
320+ switch (chn->driver->id) {
321+ case BLKID_CHAIN_SUBLKS:
322+ if (!(chn->flags & BLKID_SUBLKS_MAGIC))
323+ return 0;
324+ rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len);
325+ if (!rc)
326+ rc = blkid_probe_sprintf_value(pr,
327+ "SBMAGIC_OFFSET", "%llu", offset);
328+ break;
329+ case BLKID_CHAIN_PARTS:
330+ if (!(chn->flags & BLKID_PARTS_MAGIC))
331+ return 0;
332+ rc = blkid_probe_set_value(pr, "PTMAGIC", magic, len);
333+ if (!rc)
334+ rc = blkid_probe_sprintf_value(pr,
335+ "PTMAGIC_OFFSET", "%llu", offset);
336+ break;
337+ default:
338+ break;
339+ }
340+
341+ return rc;
342+}
343+
344 /**
345 * blkid_probe_get_devno:
346 * @pr: probe
347
348=== modified file 'libblkid/src/superblocks/superblocks.c'
349--- libblkid/src/superblocks/superblocks.c 2011-11-03 15:38:23 +0000
350+++ libblkid/src/superblocks/superblocks.c 2014-10-10 06:30:46 +0000
351@@ -478,21 +478,6 @@
352 return 0;
353 }
354
355-int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
356- size_t len, unsigned char *magic)
357-{
358- int rc = 0;
359- struct blkid_chain *chn = blkid_probe_get_chain(pr);
360-
361- if (magic && len && (chn->flags & BLKID_SUBLKS_MAGIC)) {
362- rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len);
363- if (!rc)
364- rc = blkid_probe_sprintf_value(pr, "SBMAGIC_OFFSET",
365- "%llu", offset);
366- }
367- return rc;
368-}
369-
370 int blkid_probe_set_version(blkid_probe pr, const char *version)
371 {
372 struct blkid_chain *chn = blkid_probe_get_chain(pr);
373
374=== modified file 'libblkid/src/superblocks/superblocks.h'
375--- libblkid/src/superblocks/superblocks.h 2011-11-03 15:38:23 +0000
376+++ libblkid/src/superblocks/superblocks.h 2014-10-10 06:30:46 +0000
377@@ -71,8 +71,6 @@
378 /*
379 * superblock functions
380 */
381-extern int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
382- size_t len, unsigned char *magic);
383 extern int blkid_probe_set_version(blkid_probe pr, const char *version);
384 extern int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
385 __attribute__ ((format (printf, 2, 3)));
386
387=== modified file 'misc-utils/wipefs.c'
388--- misc-utils/wipefs.c 2012-09-06 05:47:03 +0000
389+++ misc-utils/wipefs.c 2014-10-10 06:30:46 +0000
390@@ -49,6 +49,8 @@
391 char *label; /* FS label */
392 char *uuid; /* FS uuid */
393
394+ int on_disk;
395+
396 struct wipe_desc *next;
397 };
398
399@@ -138,73 +140,103 @@
400 }
401
402 static struct wipe_desc *
403-get_offset_from_probe(struct wipe_desc *wp, blkid_probe pr, int zap)
404+get_desc_for_probe(struct wipe_desc *wp, blkid_probe pr)
405 {
406- const char *off, *type, *usage, *mag;
407+ const char *off, *type, *mag, *p, *usage = NULL;
408 size_t len;
409-
410- if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) == 0 &&
411- blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL) == 0 &&
412- blkid_probe_lookup_value(pr, "SBMAGIC", &mag, &len) == 0 &&
413- blkid_probe_lookup_value(pr, "USAGE", &usage, NULL) == 0) {
414-
415- loff_t offset = strtoll(off, NULL, 10);
416- const char *p;
417-
418- wp = add_offset(wp, offset, zap);
419- if (!wp)
420- return NULL;
421-
422+ loff_t offset;
423+ int rc;
424+
425+ /* superblocks */
426+ if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) == 0) {
427+ rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
428+ if (!rc)
429+ rc = blkid_probe_lookup_value(pr, "SBMAGIC", &mag, &len);
430+ if (rc)
431+ return wp;
432+
433+ /* partitions */
434+ } else if (blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL) == 0) {
435+ rc = blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &off, NULL);
436+ if (!rc)
437+ rc = blkid_probe_lookup_value(pr, "PTMAGIC", &mag, &len);
438+ if (rc)
439+ return wp;
440+ usage = "partition table";
441+ } else
442+ return wp;
443+
444+ offset = strtoll(off, NULL, 10);
445+
446+ wp = add_offset(wp, offset, 0);
447+ if (!wp)
448+ return NULL;
449+
450+ if (usage || blkid_probe_lookup_value(pr, "USAGE", &usage, NULL) == 0)
451 wp->usage = xstrdup(usage);
452- wp->type = xstrdup(type);
453-
454- wp->magic = xmalloc(len);
455- memcpy(wp->magic, mag, len);
456- wp->len = len;
457-
458- if (blkid_probe_lookup_value(pr, "LABEL", &p, NULL) == 0)
459- wp->label = xstrdup(p);
460-
461- if (blkid_probe_lookup_value(pr, "UUID", &p, NULL) == 0)
462- wp->uuid = xstrdup(p);
463- }
464+
465+ wp->type = xstrdup(type);
466+ wp->on_disk = 1;
467+
468+ wp->magic = xmalloc(len);
469+ memcpy(wp->magic, mag, len);
470+ wp->len = len;
471+
472+ if (blkid_probe_lookup_value(pr, "LABEL", &p, NULL) == 0)
473+ wp->label = xstrdup(p);
474+
475+ if (blkid_probe_lookup_value(pr, "UUID", &p, NULL) == 0)
476+ wp->uuid = xstrdup(p);
477
478 return wp;
479 }
480
481-static struct wipe_desc *
482-read_offsets(struct wipe_desc *wp, const char *fname, int zap)
483+static blkid_probe
484+new_probe(const char *devname, int mode)
485 {
486 blkid_probe pr;
487- int rc;
488
489- if (!fname)
490+ if (!devname)
491 return NULL;
492
493- pr = blkid_new_probe_from_filename(fname);
494+ if (mode) {
495+ int fd = open(devname, mode);
496+ if (fd < 0)
497+ goto error;
498+
499+ pr = blkid_new_probe();
500+ if (pr && blkid_probe_set_device(pr, fd, 0, 0))
501+ goto error;
502+ } else
503+ pr = blkid_new_probe_from_filename(devname);
504+
505 if (!pr)
506- errx(EXIT_FAILURE, _("error: %s: probing initialization failed"), fname);
507-
508- blkid_probe_enable_superblocks(pr, 0); /* enabled by default ;-( */
509-
510- blkid_probe_enable_partitions(pr, 1);
511- rc = blkid_do_fullprobe(pr);
512- blkid_probe_enable_partitions(pr, 0);
513-
514- if (rc == 0) {
515- const char *type = NULL;
516- blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL);
517- warnx(_("WARNING: %s: appears to contain '%s' "
518- "partition table"), fname, type);
519- }
520+ goto error;
521
522 blkid_probe_enable_superblocks(pr, 1);
523 blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC |
524 BLKID_SUBLKS_TYPE | BLKID_SUBLKS_USAGE |
525 BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);
526
527+ blkid_probe_enable_partitions(pr, 1);
528+ blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
529+
530+ return pr;
531+error:
532+ err(EXIT_FAILURE, _("error: %s: probing initialization failed"), devname);
533+ return NULL;
534+}
535+
536+static struct wipe_desc *
537+read_offsets(struct wipe_desc *wp, const char *devname)
538+{
539+ blkid_probe pr = new_probe(devname, 0);
540+
541+ if (!pr)
542+ return NULL;
543+
544 while (blkid_do_probe(pr) == 0) {
545- wp = get_offset_from_probe(wp, pr, zap);
546+ wp = get_desc_for_probe(wp, pr);
547 if (!wp)
548 break;
549 }
550@@ -213,60 +245,54 @@
551 return wp;
552 }
553
554-static int
555-do_wipe_offset(int fd, struct wipe_desc *wp, const char *fname, int noact)
556-{
557- char buf[BUFSIZ];
558- off_t l;
559- size_t i, len;
560-
561- if (!wp->type) {
562- warnx(_("no magic string found at offset "
563- "0x%jx -- ignored"), wp->offset);
564- return 0;
565- }
566-
567- l = lseek(fd, wp->offset, SEEK_SET);
568- if (l == (off_t) -1)
569- err(EXIT_FAILURE, _("%s: failed to seek to offset 0x%jx"),
570- fname, wp->offset);
571-
572- len = wp->len > sizeof(buf) ? sizeof(buf) : wp->len;
573-
574- memset(buf, 0, len);
575- if (noact == 0 && write_all(fd, buf, len))
576- err(EXIT_FAILURE, _("%s: write failed"), fname);
577-
578- printf(_("%zd bytes were erased at offset 0x%jx (%s)\nthey were: "),
579- wp->len, wp->offset, wp->type);
580-
581- for (i = 0; i < len; i++) {
582- printf("%02x", wp->magic[i]);
583- if (i + 1 < len)
584- fputc(' ', stdout);
585- }
586-
587- printf("\n");
588- return 0;
589-}
590-
591-static int
592-do_wipe(struct wipe_desc *wp, const char *fname, int noact)
593-{
594- int fd;
595-
596- fd = open(fname, O_WRONLY);
597- if (fd < 0)
598- err(EXIT_FAILURE, _("%s: open failed"), fname);
599-
600- while (wp) {
601- if (wp->zap)
602- do_wipe_offset(fd, wp, fname, noact);
603- wp = wp->next;
604- }
605-
606- close(fd);
607- return 0;
608+static struct wipe_desc *
609+do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all)
610+{
611+ blkid_probe pr = new_probe(devname, O_RDWR);
612+ struct wipe_desc *w;
613+
614+ if (!pr)
615+ return NULL;
616+
617+ while (blkid_do_probe(pr) == 0) {
618+ w = get_desc_for_probe(wp, pr);
619+ if (!w)
620+ break;
621+ wp = w;
622+ if (!wp->on_disk)
623+ continue;
624+ wp->zap = all ? 1 : wp->zap;
625+ if (!wp->zap)
626+ continue;
627+
628+ if (blkid_do_wipe(pr, noact))
629+ warn(_("failed to erase %s magic string at offset 0x%08jx"),
630+ wp->type, wp->offset);
631+ else {
632+ size_t i;
633+
634+ printf(_("%zd bytes were erased at offset 0x%08jx (%s): "),
635+ wp->len, wp->offset, wp->type);
636+
637+ for (i = 0; i < wp->len; i++) {
638+ printf("%02x", wp->magic[i]);
639+ if (i + 1 < wp->len)
640+ fputc(' ', stdout);
641+ }
642+ putchar('\n');
643+ }
644+ }
645+
646+ for (w = wp; w != NULL; w = w->next) {
647+ if (!w->on_disk)
648+ warnx(_("offset 0x%jx not found"), w->offset);
649+ }
650+
651+ fsync(blkid_probe_get_fd(pr));
652+ close(blkid_probe_get_fd(pr));
653+ blkid_free_probe(pr);
654+
655+ return wp;
656 }
657
658 static void
659@@ -323,7 +349,7 @@
660 {
661 struct wipe_desc *wp = NULL;
662 int c, all = 0, has_offset = 0, noact = 0, mode = 0;
663- const char *fname;
664+ const char *devname;
665
666 static const struct option longopts[] = {
667 { "all", 0, 0, 'a' },
668@@ -372,26 +398,25 @@
669 if (optind == argc)
670 usage(stderr);
671
672- fname = argv[optind++];
673+ devname = argv[optind++];
674
675 if (optind != argc)
676 errx(EXIT_FAILURE, _("only one device as argument is currently supported."));
677
678- /* we need to wipe several times for some file systems like VFAT, see
679- * https://launchpad.net/bugs/1046665 */
680- do {
681- wp = read_offsets(wp, fname, all);
682-
683- if (wp) {
684- if (has_offset || all)
685- do_wipe(wp, fname, noact);
686- else
687- print_all(wp, mode);
688-
689- free_wipe(wp);
690- wp = NULL;
691- } else
692- break;
693- } while (!noact && all);
694+ if (!all && !has_offset) {
695+ /*
696+ * Print only
697+ */
698+ wp = read_offsets(wp, devname);
699+ if (wp)
700+ print_all(wp, mode);
701+ } else {
702+ /*
703+ * Erase
704+ */
705+ wp = do_wipe(wp, devname, noact, all);
706+ }
707+
708+ free_wipe(wp);
709 return EXIT_SUCCESS;
710 }

Subscribers

People subscribed via source and target branches

to all changes: