From: Jaromir Capik <jcapik@redhat.com>
To: util-linux@vger.kernel.org
Subject: [PATCH] fdformat: Add new switches -f/--from, -t/--to, -r/--repair
Date: Fri, 25 Jul 2014 11:29:49 -0400 (EDT) [thread overview]
Message-ID: <2139170067.22662578.1406302189694.JavaMail.zimbra@redhat.com> (raw)
In-Reply-To: <844628876.22654954.1406302034993.JavaMail.zimbra@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 512 bytes --]
Hello everyone.
The attached patch adds support for user configurable
from/to track and a basic repair mode for broken floppies.
It also fixes a recently introduced bug that causes
line breakage when printing the track number.
Please, review and share your feelings / merge.
Thanks in advance,
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: 10380 bytes --]
From d3543ce591fd34a787176993958237864049fbe0 Mon Sep 17 00:00:00 2001
From: Jaromir Capik <jcapik@redhat.com>
Date: Fri, 25 Jul 2014 17:16:56 +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 | 206 +++++++++++++++++++++++++++++++++--------------
3 files changed, 157 insertions(+), 61 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..c8b2a81 100644
--- a/disk-utils/fdformat.c
+++ b/disk-utils/fdformat.c
@@ -12,6 +12,7 @@
#include <unistd.h>
#include "c.h"
+#include "strutils.h"
#include "closestream.h"
#include "nls.h"
#include "xalloc.h"
@@ -20,74 +21,119 @@ struct floppy_struct param;
#define SECTOR_SIZE 512
-static void format_disk(int ctrl)
+
+static void format_begin(int ctrl)
+{
+ 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, unsigned int track, unsigned int head)
{
struct format_descr descr;
- unsigned int track;
+
+ descr.track = track;
+ descr.head = head;
+ if (ioctl(ctrl, FDFMTTRK, (long) &descr) < 0)
+ err(EXIT_FAILURE, "ioctl: FDFMTTRK");
+}
+
+static void seek_track_head(int ctrl, unsigned int track, unsigned int head)
+{
+ lseek(ctrl, (track * param.head + head) * param.sect * SECTOR_SIZE, SEEK_SET);
+}
+
+static void format_disk(int ctrl, unsigned int track_from, unsigned int track_to)
+{
+ unsigned int track, head;
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 (track = track_from; track <= track_to; track++) {
+ for (head = 0; head < param.head; head++) {
+ printf("%3u/%u\b\b\b\b\b", track, head);
+ fflush(stdout);
+ format_track_head(ctrl, track, head);
}
}
- 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, int repair)
{
unsigned char *data;
- unsigned int cyl;
- int fd, cyl_size, count;
+ unsigned int track, head;
+ int track_size, count, 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);
+
+ seek_track_head (ctrl, track_from, 0);
+
+ for (track = track_from; track <= track_to; track++) {
+ for (head = 0; head < param.head; head++) {
+ int read_bytes;
+
+ printf("%3u\b\b\b", 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, track, head);
+ format_end(ctrl);
+ seek_track_head (ctrl, track, head);
+ 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"),
+ track, 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, track, head);
+ format_end(ctrl);
+ seek_track_head (ctrl, track, head);
+ retries_left--;
+ if (retries_left) continue;
+ }
+ printf(_("bad data in track/head %u/%u\n"
+ "Continuing ... "), track, 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 +142,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 +158,45 @@ int main(int argc, char **argv)
int ch;
int ctrl;
int verify = 1;
+ int repair = 0;
+ int track_from = 0;
+ int track_to = -1;
+ unsigned long arg;
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':
+ arg = strtoul_or_err(optarg, _("invalid argument - from"));
+ if (arg > INT_MAX) err(EXIT_FAILURE, _("invalid argument - from"));
+ track_from = arg;
+ break;
+ case 't':
+ arg = strtoul_or_err(optarg, _("invalid argument - to"));
+ if (arg > INT_MAX) err(EXIT_FAILURE, _("invalid argument - to"));
+ track_to = arg;
+ break;
+ case 'r':
+ arg = strtoul_or_err(optarg, _("invalid argument - repair"));
+ if (arg > INT_MAX) err(EXIT_FAILURE, _("invalid argument - repair"));
+ repair = arg;
+ break;
case 'n':
verify = 0;
break;
@@ -149,20 +222,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)¶m) < 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 (track_to == -1)
+ track_to = param.track - 1;
+
+ if ((unsigned int)track_from > param.track - 1)
+ err(EXIT_FAILURE, _("'from' is out of allowed range\n"));
+ if ((unsigned int)track_to > param.track - 1)
+ err(EXIT_FAILURE, _("'to' is out of allowed range\n"));
+ if (track_from > track_to)
+ err(EXIT_FAILURE, _("'from' is higher than 'to'\n"));
+
+ 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
next parent reply other threads:[~2014-07-25 15:29 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 ` Jaromir Capik [this message]
2014-07-26 10:40 ` [PATCH] fdformat: Add new switches -f/--from, -t/--to, -r/--repair 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
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=2139170067.22662578.1406302189694.JavaMail.zimbra@redhat.com \
--to=jcapik@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.