All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jaromir Capik <jcapik@redhat.com>
To: Karel Zak <kzak@redhat.com>
Cc: kerolasa@gmail.com, util-linux <util-linux@vger.kernel.org>
Subject: Re: [PATCH] fdformat: Add new switches -f/--from, -t/--to, -r/--repair
Date: Tue, 29 Jul 2014 07:32:03 -0400 (EDT)	[thread overview]
Message-ID: <1340617573.25924027.1406633523481.JavaMail.zimbra@redhat.com> (raw)
In-Reply-To: <20140728151034.GM8533@x2.net.home>

[-- Attachment #1: Type: text/plain, Size: 301 bytes --]

Hello guys. 

The reworked patch is attached. 

Please, review once more. 

Thanks, 
Jaromir. 

--
Jaromir Capik
Red Hat Czech, s.r.o.
Software Engineer / Secondary Arch

Email: jcapik@redhat.com
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkynova 99/71, 612 45, Brno, Czech Republic
IC: 27690016 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fdformat-from-to-repair.patch --]
[-- Type: text/x-patch; name=fdformat-from-to-repair.patch, Size: 10564 bytes --]

From 9b9954ec709cdb5ba44b142aa96dac9fdc09cac2 Mon Sep 17 00:00:00 2001
From: Jaromir Capik <jcapik@redhat.com>
Date: Mon, 28 Jul 2014 20:47:09 +0200
Subject: [PATCH] fdformat: Add new switches -f/--from, -t/--to, -r/--repair

This commit introduces a support for user configurable
from/to track and a basic repair mode for broken floppies.
It also fixes a recently introduced bug that causes
a line breakage when printing the track number.
---
 disk-utils/Makemodule.am |   1 +
 disk-utils/fdformat.8    |  11 ++-
 disk-utils/fdformat.c    | 210 ++++++++++++++++++++++++++++++++---------------
 3 files changed, 157 insertions(+), 65 deletions(-)

diff --git a/disk-utils/Makemodule.am b/disk-utils/Makemodule.am
index c6183f5..995e085 100644
--- a/disk-utils/Makemodule.am
+++ b/disk-utils/Makemodule.am
@@ -110,6 +110,7 @@ if BUILD_FDFORMAT
 usrsbin_exec_PROGRAMS += fdformat
 dist_man_MANS += disk-utils/fdformat.8
 fdformat_SOURCES = disk-utils/fdformat.c
+fdformat_LDADD = $(LDADD) libcommon.la
 endif
 
 if BUILD_BLOCKDEV
diff --git a/disk-utils/fdformat.8 b/disk-utils/fdformat.8
index df4153f..797f50f 100644
--- a/disk-utils/fdformat.8
+++ b/disk-utils/fdformat.8
@@ -1,6 +1,6 @@
 .\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
 .\" May be distributed under the GNU General Public License
-.TH FDFORMAT 8 "July 2011" "util-linux" "System Administration"
+.TH FDFORMAT 8 "July 2014" "util-linux" "System Administration"
 .SH NAME
 fdformat \- low-level format a floppy disk
 .SH SYNOPSIS
@@ -45,6 +45,15 @@ autodetected earlier.  In this case, use
 to load the disk parameters.
 .SH OPTIONS
 .TP
+\fB\-f\fR, \fB\-\-from\fR \fIN\fR
+Start at the track \fIN\fR (default is 0).
+.TP
+\fB\-t\fR, \fB\-\-to\fR \fIN\fR
+Stop at the track \fIN\fR (default is 0).
+.TP
+\fB\-r\fR, \fB\-\-repair\fR \fIN\fR
+Try to repair tracks failed during the verification (max \fIN\fR retries).
+.TP
 \fB\-n\fR, \fB\-\-no-verify\fR
 Skip the verification that is normally performed after the formatting.
 .TP
diff --git a/disk-utils/fdformat.c b/disk-utils/fdformat.c
index e6ae8e4..dc98de5 100644
--- a/disk-utils/fdformat.c
+++ b/disk-utils/fdformat.c
@@ -12,82 +12,129 @@
 #include <unistd.h>
 
 #include "c.h"
+#include "strutils.h"
 #include "closestream.h"
 #include "nls.h"
 #include "xalloc.h"
 
+#define SECTOR_SIZE 512
+
 struct floppy_struct param;
 
-#define SECTOR_SIZE 512
 
-static void format_disk(int ctrl)
+static void format_begin(int ctrl)
 {
-	struct format_descr descr;
-	unsigned int track;
+	if (ioctl(ctrl, FDFMTBEG, NULL) < 0)
+		err(EXIT_FAILURE, "ioctl: FDFMTBEG");
+}
+
+static void format_end(int ctrl)
+{
+	if (ioctl(ctrl, FDFMTEND, NULL) < 0)
+		err(EXIT_FAILURE, "ioctl: FDFMTEND");
+}
+
+static void format_track_head(int ctrl, struct format_descr *descr)
+{
+	if (ioctl(ctrl, FDFMTTRK, (long) descr) < 0)
+		err(EXIT_FAILURE, "ioctl: FDFMTTRK");
+}
+
+static void seek_track_head(int ctrl, struct format_descr *descr)
+{
+	lseek(ctrl, (descr->track * param.head + descr->head) * param.sect * SECTOR_SIZE, SEEK_SET);
+}
+
+static void format_disk(int ctrl, unsigned int track_from, unsigned int track_to)
+{
+	struct format_descr current;
 
 	printf(_("Formatting ... "));
 	fflush(stdout);
-	if (ioctl(ctrl, FDFMTBEG, NULL) < 0)
-		err(EXIT_FAILURE, "ioctl: FDFMTBEG");
-	for (track = 0; track < param.track; track++) {
-		descr.track = track;
-		descr.head = 0;
-		if (ioctl(ctrl, FDFMTTRK, (long) &descr) < 0)
-			err(EXIT_FAILURE, "ioctl: FDFMTTRK");
-
-		printf("%3ud\b\b\b", track);
-		fflush(stdout);
-		if (param.head == 2) {
-			descr.head = 1;
-			if (ioctl(ctrl, FDFMTTRK, (long)&descr) < 0)
-				err(EXIT_FAILURE, "ioctl: FDFMTTRK");
+
+	format_begin(ctrl);
+
+	for (current.track = track_from; current.track <= track_to; current.track++) {
+		for (current.head = 0; current.head < param.head; current.head++) {
+			printf("%3u/%u\b\b\b\b\b", current.track, current.head);
+			fflush(stdout);
+			format_track_head(ctrl, &current);
 		}
 	}
-	if (ioctl(ctrl, FDFMTEND, NULL) < 0)
-		err(EXIT_FAILURE, "ioctl: FDFMTEND");
+
+	format_end(ctrl);
+
 	printf(_("done\n"));
 }
 
-static void verify_disk(char *name)
+static void verify_disk(int ctrl, unsigned int track_from, unsigned int track_to, unsigned int repair)
 {
 	unsigned char *data;
-	unsigned int cyl;
-	int fd, cyl_size, count;
+	struct format_descr current;
+	int track_size, count;
+	unsigned int retries_left;
 
-	cyl_size = param.sect * param.head * 512;
-	data = xmalloc(cyl_size);
+	track_size = param.sect * SECTOR_SIZE;
+	data = xmalloc(track_size);
 	printf(_("Verifying ... "));
 	fflush(stdout);
-	if ((fd = open(name, O_RDONLY)) < 0)
-		err(EXIT_FAILURE, _("cannot open %s"), name);
-	for (cyl = 0; cyl < param.track; cyl++) {
-		int read_bytes;
-
-		printf("%u3d\b\b\b", cyl);
-		fflush(stdout);
-		read_bytes = read(fd, data, cyl_size);
-		if (read_bytes != cyl_size) {
-			if (read_bytes < 0)
-				perror(_("Read: "));
-			fprintf(stderr,
-				_("Problem reading cylinder %d,"
-				  " expected %d, read %d\n"),
-				cyl, cyl_size, read_bytes);
-			free(data);
-			exit(EXIT_FAILURE);
-		}
-		for (count = 0; count < cyl_size; count++)
-			if (data[count] != FD_FILL_BYTE) {
-				printf(_("bad data in cyl %d\n"
-					 "Continuing ... "), cyl);
-				fflush(stdout);
+
+	current.track = track_from;
+	current.head = 0;
+	seek_track_head (ctrl, &current);
+
+	for (current.track = track_from; current.track <= track_to; current.track++) {
+		for (current.head = 0; current.head < param.head; current.head++) {
+			int read_bytes;
+
+			printf("%3u\b\b\b", current.track);
+			fflush(stdout);
+
+			retries_left = repair;
+			do {
+				read_bytes = read(ctrl, data, track_size);
+				if (read_bytes != track_size) {
+					if (retries_left) {
+						format_begin(ctrl);
+						format_track_head(ctrl, &current);
+						format_end(ctrl);
+						seek_track_head (ctrl, &current);
+						retries_left--;
+						if (retries_left)
+							continue;
+					}
+					if (read_bytes < 0)
+						perror(_("Read: "));
+					fprintf(stderr,
+						_("Problem reading track/head %u/%u,"
+						  " expected %d, read %d\n"),
+						current.track, current.head, track_size, read_bytes);
+					free(data);
+					exit(EXIT_FAILURE);
+				}
+				for (count = 0; count < track_size; count++)
+					if (data[count] != FD_FILL_BYTE) {
+						if (retries_left) {
+							format_begin(ctrl);
+							format_track_head(ctrl, &current);
+							format_end(ctrl);
+							seek_track_head (ctrl, &current);
+							retries_left--;
+							if (retries_left)
+								continue;
+						}
+						printf(_("bad data in track/head %u/%u\n"
+							 "Continuing ... "), current.track, current.head);
+						fflush(stdout);
+						break;
+					}
 				break;
-			}
+			} while (retries_left);
+		}
 	}
+
 	free(data);
 	printf(_("done\n"));
-	if (close(fd) < 0)
-		err(EXIT_FAILURE, "close");
 }
 
 static void __attribute__ ((__noreturn__)) usage(FILE * out)
@@ -96,9 +143,13 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
 		program_invocation_short_name);
 
 	fprintf(out, _("\nOptions:\n"
-		       " -n, --no-verify  disable the verification after the format\n"
-		       " -V, --version    output version information and exit\n"
-		       " -h, --help       display this help and exit\n\n"));
+		       " -f, --from <N>    start at the track N (default 0)\n"
+		       " -t, --to <N>      stop at the track N\n"
+		       " -r, --repair <N>  try to repair tracks failed during\n"
+		       "                   the verification (max N retries)\n"
+		       " -n, --no-verify   disable the verification after the format\n"
+		       " -V, --version     output version information and exit\n"
+		       " -h, --help        display this help and exit\n\n"));
 
 	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
 }
@@ -108,22 +159,40 @@ int main(int argc, char **argv)
 	int ch;
 	int ctrl;
 	int verify = 1;
+	unsigned int repair = 0;
+	unsigned int track_from = 0;
+	unsigned int track_to = 0;
+	int has_user_defined_track_to = 0;
 	struct stat st;
 
 	static const struct option longopts[] = {
+		{"from", required_argument, NULL, 'f'},
+		{"to", required_argument, NULL, 't'},
+		{"repair", required_argument, NULL, 'r'},
 		{"no-verify", no_argument, NULL, 'n'},
 		{"version", no_argument, NULL, 'V'},
 		{"help", no_argument, NULL, 'h'},
 		{NULL, 0, NULL, 0}
 	};
 
+
 	setlocale(LC_ALL, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 	atexit(close_stdout);
 
-	while ((ch = getopt_long(argc, argv, "nVh", longopts, NULL)) != -1)
+	while ((ch = getopt_long(argc, argv, "f:t:r:nVh", longopts, NULL)) != -1)
 		switch (ch) {
+		case 'f':
+			track_from = strtou32_or_err(optarg, _("invalid argument - from"));
+			break;
+		case 't':
+			has_user_defined_track_to = 1;
+			track_to = strtou32_or_err(optarg, _("invalid argument - to"));
+			break;
+		case 'r':
+			repair = strtou32_or_err(optarg, _("invalid argument - repair"));
+			break;
 		case 'n':
 			verify = 0;
 			break;
@@ -149,20 +218,33 @@ int main(int argc, char **argv)
 	if (access(argv[0], W_OK) < 0)
 		err(EXIT_FAILURE, _("cannot access file %s"), argv[0]);
 
-	ctrl = open(argv[0], O_WRONLY);
+	ctrl = open(argv[0], O_RDWR);
 	if (ctrl < 0)
 		err(EXIT_FAILURE, _("cannot open %s"), argv[0]);
-	if (ioctl(ctrl, FDGETPRM, (long)&param) < 0)
-		err(EXIT_FAILURE, _("Could not determine current format type"));
+	if (ioctl(ctrl, FDGETPRM, (long) &param) < 0)
+		err(EXIT_FAILURE, _("could not determine current format type"));
 
 	printf(_("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n"),
-	       (param.head == 2) ? _("Double") : _("Single"),
-	       param.track, param.sect, param.size >> 1);
-	format_disk(ctrl);
-	if (close_fd(ctrl) != 0)
-		err(EXIT_FAILURE, _("write failed"));
+		(param.head == 2) ? _("Double") : _("Single"),
+		param.track, param.sect, param.size >> 1);
+
+	if (!has_user_defined_track_to)
+		track_to = param.track - 1;
+
+	if (track_from >= param.track)
+		err(EXIT_FAILURE, _("user defined start track exceeds the medium specific maximum"));
+	if (track_to >= param.track)
+		err(EXIT_FAILURE, _("user defined end track exceeds the medium specific maximum"));
+	if (track_from > track_to)
+		err(EXIT_FAILURE, _("user defined start track exceeds the user defined end track"));
+
+	format_disk(ctrl, track_from, track_to);
 
 	if (verify)
-		verify_disk(argv[0]);
+		verify_disk(ctrl, track_from, track_to, repair);
+
+	if (close_fd(ctrl) != 0)
+		err(EXIT_FAILURE, _("close failed"));
+
 	return EXIT_SUCCESS;
 }
-- 
1.9.3


  parent reply	other threads:[~2014-07-29 11:32 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <844628876.22654954.1406302034993.JavaMail.zimbra@redhat.com>
2014-07-25 15:29 ` [PATCH] fdformat: Add new switches -f/--from, -t/--to, -r/--repair Jaromir Capik
2014-07-26 10:40   ` Sami Kerola
2014-07-28 14:38     ` Jaromir Capik
2014-07-28 15:10       ` Karel Zak
2014-07-28 16:01         ` Jaromir Capik
2014-07-28 19:15           ` Jaromir Capik
2014-07-29 11:32         ` Jaromir Capik [this message]
2014-07-29 11:53           ` Karel Zak
2014-09-08 17:50           ` Jaromir Capik
2014-09-16  9:15             ` Karel Zak

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=1340617573.25924027.1406633523481.JavaMail.zimbra@redhat.com \
    --to=jcapik@redhat.com \
    --cc=kerolasa@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.