util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Lukas Czerner <lczerner@redhat.com>
To: util-linux@vger.kernel.org
Cc: kzak@redhat.com
Subject: [PATCH] blkdiscard: Refuse to proceed if signatures are found
Date: Thu, 18 Jun 2020 11:29:16 +0200	[thread overview]
Message-ID: <20200618092916.12191-1-lczerner@redhat.com> (raw)

Currently the blkdiscard has the ability to wipe out entere device in a
matter of seconds. This is fine as long as it's intentional, it is
potentially catastrophic if it's not.

With this commit blkdiscard will check for existing signatures on the
device and refuse to continue if any are found unless the operation is
forced with the -f option.

In an attempt to avoid breaking existing automation scripts the force is
only required when stdin refers to a terminal.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
 sys-utils/Makemodule.am |  2 +-
 sys-utils/blkdiscard.c  | 54 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 5855e1cc1..b5f6c1b1b 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -165,7 +165,7 @@ if BUILD_BLKDISCARD
 sbin_PROGRAMS += blkdiscard
 dist_man_MANS += sys-utils/blkdiscard.8
 blkdiscard_SOURCES = sys-utils/blkdiscard.c lib/monotonic.c
-blkdiscard_LDADD = $(LDADD) libcommon.la $(REALTIME_LIBS)
+blkdiscard_LDADD = $(LDADD) libblkid.la libcommon.la $(REALTIME_LIBS)
 endif
 
 if BUILD_BLKZONE
diff --git a/sys-utils/blkdiscard.c b/sys-utils/blkdiscard.c
index e83f69b11..f9eb6b7b0 100644
--- a/sys-utils/blkdiscard.c
+++ b/sys-utils/blkdiscard.c
@@ -37,6 +37,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <linux/fs.h>
+#include <blkid/blkid.h>
 
 #include "nls.h"
 #include "strutils.h"
@@ -106,11 +107,45 @@ static void __attribute__((__noreturn__)) usage(void)
 	exit(EXIT_SUCCESS);
 }
 
+/*
+ * Check existing signature on the open fd
+ * Returns	0  if no signature was found
+ * 		1  if a signature was found
+ * 		<0 on error
+ */
+static int device_empty(int fd, char *path)
+{
+	const char *type;
+	blkid_probe pr = NULL;
+	int ret = -1;
+
+	pr = blkid_new_probe();
+	if (!pr || blkid_probe_set_device(pr, fd, 0, 0))
+		return ret;
+
+	blkid_probe_enable_superblocks(pr, TRUE);
+	blkid_probe_enable_partitions(pr, TRUE);
+
+	ret = blkid_do_fullprobe(pr);
+	if (ret)
+		return ret;
+
+	if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
+		warnx("%s contains existing file system (%s).",path ,type);
+	} else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
+		warnx("%s contains existing partition (%s).",path ,type);
+	} else {
+		warnx("%s contains existing signature.", path);
+	}
+
+	blkid_free_probe(pr);
+	return ret;
+}
 
 int main(int argc, char **argv)
 {
 	char *path;
-	int c, fd, verbose = 0, secsize, force = 0;
+	int c, fd, ret, verbose = 0, secsize, force = 0;
 	uint64_t end, blksize, step, range[2], stats[2];
 	struct stat sb;
 	struct timeval now, last;
@@ -184,7 +219,7 @@ int main(int argc, char **argv)
 		errtryhelp(EXIT_FAILURE);
 	}
 
-	fd = open(path, O_WRONLY | (force ? 0 : O_EXCL));
+	fd = open(path, O_RDWR | (force ? 0 : O_EXCL));
 	if (fd < 0)
 		err(EXIT_FAILURE, _("cannot open %s"), path);
 
@@ -217,6 +252,21 @@ int main(int argc, char **argv)
 		errx(EXIT_FAILURE, _("%s: length %" PRIu64 " is not aligned "
 			 "to sector size %i"), path, range[1], secsize);
 
+	 /* Check for existing signatures on the device */
+	if ((ret = device_empty(fd, path)) == 0) {
+		/*
+		 * Only require force in interactive mode to avoid
+		 * breaking existing scripts
+		 */
+		if (!force && isatty(STDIN_FILENO)) {
+			errx(EXIT_FAILURE,
+			     _("This is destructive operation, data will " \
+			       "be lost! Use the -f option to override."));
+		}
+		warnx(_("Operation forced, data will be lost!"));
+	} else if (ret < 0)
+		err(EXIT_FAILURE, _("failed to probe the device"));
+
 	stats[0] = range[0], stats[1] = 0;
 	gettime_monotonic(&last);
 
-- 
2.21.3


             reply	other threads:[~2020-06-18  9:29 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-18  9:29 Lukas Czerner [this message]
2020-06-18 10:06 ` [PATCH] blkdiscard: Refuse to proceed if signatures are found Karel Zak
2020-06-18 10:33   ` Lukas Czerner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200618092916.12191-1-lczerner@redhat.com \
    --to=lczerner@redhat.com \
    --cc=kzak@redhat.com \
    --cc=util-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).