SHA256
1
0
forked from pool/s390-tools
s390-tools/s390-tools-sles12sp3-dasdfmt-08-Make-progress-output-reusable-and-add-ETR.patch
2017-02-21 11:14:26 +00:00

280 lines
7.5 KiB
Diff

Subject: [PATCH] [FEAT LS1501] dasdfmt: Add new formatting modes
From: Jan Höppner <hoeppner@linux.vnet.ibm.com>
Summary: dasdfmt: Add new formatting modes
Description: Introduce new formatting modes 'quick' and 'expand' to either
format an earlier formatted DASD that could potentially be
re-initialized very easily or format unformatted tracks at the
end of a device that was previously extended.
Also add the command line argument --check to provide a function
that checks a DASD volume for correct formatting.
Upstream-ID: -
Problem-ID: LS1501
Upstream-Description:
dasdfmt: Make progress output reusable and add ETR
The progress indicator (in form of a progressbar, hashmarks or
percentages) is created within the formatting loop.
Put the drawing of the progress into a separate function to make it
reusable. Clean up the formatting loop while at it and make it
more readable. Also, add the estimated time remaining to the output.
Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com>
---
dasdfmt/dasdfmt.c | 198 +++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 138 insertions(+), 60 deletions(-)
--- a/dasdfmt/dasdfmt.c
+++ b/dasdfmt/dasdfmt.c
@@ -11,6 +11,7 @@
#include <sys/utsname.h>
#include <linux/version.h>
+#include <sys/time.h>
#include "zt_common.h"
#include "dasdfmt.h"
@@ -20,6 +21,8 @@
#include <sys/wait.h>
#define BUSIDSIZE 8
+#define SEC_PER_DAY (60 * 60 * 24)
+#define SEC_PER_HOUR (60 * 60)
/* Full tool name */
static const char tool_name[] = "dasdfmt: zSeries DASD format program";
@@ -88,6 +91,120 @@ static void exit_usage(int exitcode)
exit(exitcode);
}
+/*
+ * Helper function to calculate the days, hours, minutes, and seconds
+ * for a given timestamp in seconds
+ */
+static void calc_time(time_t time, int *d, int *h, int *m, int *s)
+{
+ *d = time / SEC_PER_DAY;
+ time %= SEC_PER_DAY;
+ *h = time / SEC_PER_HOUR;
+ time %= SEC_PER_HOUR;
+ *m = time / 60;
+ *s = time % 60;
+}
+
+/*
+ * This function calculates and prints the estimated time remaining.
+ */
+static void print_etr(int p_new, int started)
+{
+ static struct timeval start;
+ struct timeval now;
+ time_t time_elapsed;
+ time_t time_end;
+ int d, h, m, s;
+ static int p_init;
+ int p;
+
+ if (!started) {
+ gettimeofday(&start, NULL);
+ p_init = p_new;
+ }
+ gettimeofday(&now, NULL);
+ time_elapsed = now.tv_sec - start.tv_sec;
+
+ /*
+ * We might start somewhere in the middle with an initial percentage
+ * value of i.e. 60%. Therefore we need to calculate the relative
+ * percentage of p_new within that remaining range (100 - 60) in order
+ * to correctly estimate the remaining time.
+ */
+ if (p_init == 100)
+ p = p_init;
+ else
+ p = 100 * (p_new - p_init) / (100 - p_init);
+
+ if (p == 0)
+ time_end = time_elapsed;
+ else
+ time_end = time_elapsed * (100 - p) / p;
+
+ /* Calculate days, hours, minutes, and seconds */
+ calc_time(time_end, &d, &h, &m, &s);
+ if (p_new == 100)
+ calc_time(time_elapsed, &d, &h, &m, &s);
+
+ /* Avoid printing leading zeros */
+ if (d > 0)
+ printf(" [%dd %dh %dm %ds%-4s", d, h, m, s, "]");
+ else if (h > 0)
+ printf(" [%dh %dm %ds%-7s", h, m, s, "]");
+ else if (m > 0)
+ printf(" [%dm %ds%-6s", m, s, "]");
+ else if (s > 0 || p > 50)
+ printf(" [%ds%-5s", s, "]");
+ else
+ printf(" [--%-1s", "]");
+}
+
+/*
+ * Draw the progress indicator depending on what command line argument is set.
+ * This can either be a progressbar, hashmarks, or percentage.
+ */
+static void draw_progress(dasdfmt_info_t *info, int cyl, unsigned int cylinders)
+{
+ static int hashcount;
+ static int started;
+ static int p_old;
+ int p_new = 0;
+ int barlength;
+ int i;
+
+ if (info->print_progressbar) {
+ printf("cyl %7d of %7d |", cyl, cylinders);
+ p_new = cyl * 100 / cylinders;
+ if (p_new != p_old || !started) {
+ /* percent value has changed */
+ p_old = p_new;
+ barlength = cyl * 33 / cylinders;
+ for (i = 1; i <= barlength; i++)
+ printf("#");
+ for (i = barlength + 1; i <= 33; i++)
+ printf("-");
+ printf("|%3d%%", p_new);
+ print_etr(p_new, started);
+ started = 1;
+ }
+ printf("\r");
+ fflush(stdout);
+ }
+
+ if (info->print_hashmarks &&
+ (cyl / info->hashstep - hashcount) != 0) {
+ printf("%d|", info->procnum);
+ fflush(stdout);
+ hashcount++;
+ }
+
+ if (info->print_percentage) {
+ printf("cyl %7d of %7d |%3d%%\n", cyl, cylinders,
+ cyl * 100 / cylinders);
+ fflush(stdout);
+ }
+}
+
static int reread_partition_table(void)
{
int i = 0;
@@ -906,9 +1023,10 @@ static void dasdfmt_write_labels(dasdfmt
static void dasdfmt_format(dasdfmt_info_t *info, unsigned int cylinders,
unsigned int heads, format_data_t *format_params)
{
- format_data_t format_step;
- int j, cyl, tmp, p1, p2, hashcount = 0;
- unsigned int k;
+ unsigned int step_value;
+ unsigned long cur_trk;
+ format_data_t step;
+ int cyl = 0;
if (info->print_hashmarks) {
if (info->hashstep < reqsize)
@@ -923,73 +1041,33 @@ static void dasdfmt_format(dasdfmt_info_
info->hashstep);
}
- format_step.blksize = format_params->blksize;
- format_step.intensity = format_params->intensity;
-
- k = 0;
- cyl = 1;
- if ((info->print_progressbar || info->print_hashmarks) && !info->yast_mode)
- printf("\n");
-
- while (1) {
- p1 = -1;
- p2 = 0;
- if (k + heads * reqsize >= format_params->stop_unit)
- reqsize = 1;
- format_step.start_unit = k;
- format_step.stop_unit = k + reqsize * heads - 1;
+ step = *format_params;
+ cur_trk = format_params->start_unit;
- if (cyl == 1)
- format_step.start_unit += 1;
+ while (cur_trk < format_params->stop_unit) {
+ step_value = reqsize * heads - (cur_trk % heads);
+ step.start_unit = cur_trk;
+ if (cur_trk + reqsize * heads >= format_params->stop_unit)
+ step.stop_unit = format_params->stop_unit;
+ else
+ step.stop_unit = cur_trk + step_value - 1;
- if (ioctl(filedes, BIODASDFMT, &format_step) != 0)
+ if (ioctl(filedes, BIODASDFMT, &step) != 0)
ERRMSG_EXIT(EXIT_FAILURE, "%s: (format cylinder) IOCTL "
"BIODASDFMT failed. (%s)\n",
prog_name, strerror(errno));
- if (info->print_progressbar) {
- printf("cyl %7d of %7d |", cyl, cylinders);
- p2 = p1;
- p1 = cyl * 100 / cylinders;
- if (p1 != p2) {
- /* percent value has changed */
- tmp = cyl * 50 / cylinders;
- for (j = 1; j <= tmp; j++)
- printf("#");
- for (j = tmp + 1; j <= 50; j++)
- printf("-");
- printf("|%3d%%", p1);
- }
- printf("\r");
- fflush(stdout);
- }
-
- if (info->print_hashmarks)
- if ((cyl / info->hashstep - hashcount) != 0) {
- printf("%d|",info->procnum);
- fflush(stdout);
- hashcount++;
- }
-
- if (info->print_percentage) {
- printf("cyl %7d of %7d |%3d%%\n", cyl, cylinders,
- cyl*100/cylinders);
- fflush(stdout);
- }
+ cyl = cur_trk / heads + 1;
+ draw_progress(info, cyl, cylinders);
- if (k % heads == 0) {
- k += reqsize * heads;
- cyl += reqsize;
- } else {
- k += format_params->stop_unit % heads;
- }
-
- if (k > format_params->stop_unit)
- break;
+ cur_trk += step_value;
}
+ /* We're done, draw the 100% mark */
+ cyl = step.stop_unit / heads + 1;
+ draw_progress(info, cyl, cylinders);
if ((info->print_progressbar || info->print_hashmarks) && !info->yast_mode)
- printf("\n\n");
+ printf("\n");
}
static void dasdfmt_prepare_and_format(dasdfmt_info_t *info,