forked from pool/s390-tools
Marcus Meissner
9b729e2acc
New package per "Factory first" policy. Please list me as bug owner and maintainer, if possible. OBS-URL: https://build.opensuse.org/request/show/459343 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=1
280 lines
7.5 KiB
Diff
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,
|