Blob Blame History Raw
From afe16490113999868ff408ff303ac7df4b733ff5 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Dan=20Hor=C3=A1k?= <dan@danny.cz>
Date: Thu, 23 Apr 2009 11:47:13 +0200
Subject: [PATCH] s390-tools-1.8.1-ziorep-fixes

---
 ziomon/stats.h                |    9 ++++---
 ziomon/ziomon                 |   13 +++++++----
 ziomon/ziorep_config          |   23 +++++++++++----------
 ziomon/ziorep_traffic.cpp     |   31 +++++++++++++++++------------
 ziomon/ziorep_utilization.cpp |    4 +-
 ziomon/ziorep_utils.cpp       |   43 +++++++++++++++++++++++++++++++++++-----
 6 files changed, 82 insertions(+), 41 deletions(-)

diff --git a/ziomon/stats.h b/ziomon/stats.h
index 1003f91..a28d436 100644
--- a/ziomon/stats.h
+++ b/ziomon/stats.h
@@ -108,7 +108,7 @@ static inline int histlog2_index(__u64 val, struct histlog2 *h)
 {
 	int i;
 
-	for (i = 0; i < (h->num - 1) && val > histlog2_upper_limit(i, h); i++);
+	for (i = 0; i < h->num && val > histlog2_upper_limit(i, h); i++);
 	return i;
 }
 
@@ -123,15 +123,16 @@ static inline void histlog2_merge(struct histlog2 *h, __u32 *dst, const __u32 *s
 {
 	int i;
 
-	for (i = 0; i < h->num - 1; i++)
+	for (i = 0; i < h->num; i++) {
 		dst[i] += src[i];
+	}
 }
 
 static inline void histlog2_swap(__u32 a[], struct histlog2 *h)
 {
 	int i;
 
-	for (i = 0; i < h->num - 1; i++)
+	for (i = 0; i < h->num; i++)
 		swap_32(a[i]);
 }
 
@@ -141,7 +142,7 @@ static inline void histlog2_print(const char *s, const __u32 a[],
 	int i;
 
 	printf("%s:\n", s);
-	for (i = 0; i < h->num - 1; i++) {
+	for (i = 0; i < h->num; i++) {
 		printf("   %10ld:%6d",
 			(unsigned long)(histlog2_upper_limit(i, h)), a[i]);
 		if (!((i + 1) % 4))
diff --git a/ziomon/ziomon b/ziomon/ziomon
index 30c8adf..aa1cf78 100755
--- a/ziomon/ziomon
+++ b/ziomon/ziomon
@@ -411,14 +411,14 @@ function check_for_multipath_devices() {
                devices_basenames[$j]="";
                clean_devices;
                (( i+=3 ));
-               while [ "${mp_arr[$i]:0:1}" == "_" ]; do
+               while [[ ! "${mp_arr[$i]:0:1}" =~ "[0-9a-zA-Z]" ]] && [ $i -lt ${#mp_arr[@]} ]; do
                   checked_devs[${#checked_devs[@]}]=`echo ${mp_arr[$i]} | awk '{print "/dev/"$3}'`;
                   ddebug "   add ${checked_devs[${#checked_devs[@]}-1]}";
-                  line=${mp_arr[$i]#_*};
+                  line=${mp_arr[$i]#* };
                   line=${line%%:*};
                   line=`echo $line | sed 's/ //g'`;
                   WRP_HOST_ADAPTERS[${#WRP_HOST_ADAPTERS[@]}]="host$line";
-                  WRP_LUNS[${#WRP_LUNS[@]}]=`echo ${mp_arr[$i]#_*} | awk '{print $1}'`;
+                  WRP_LUNS[${#WRP_LUNS[@]}]=`echo ${mp_arr[$i]#* } | awk '{print $1}'`;
                   (( i++ ));
                done;
                (( --i ));
@@ -599,6 +599,7 @@ function check_size_requirements() {
    local estimated_size;
    local free_space;
    local logpath=`dirname $WRP_LOGFILE`;
+   local num_uniq_devs;
 
    set `ziomon_mgr -e`;
    util_base_sz=$1;
@@ -610,10 +611,12 @@ function check_size_requirements() {
 
    # NOTE: Since blktrace and ziomon_zfcpdd write messages only when there is
    # traffic, the estimate is an upper boundary only
+   num_uniq_devs=`echo ${WRP_LUNS[@]} | sed 's/ /\n/g' | cut -d : -f 4 | sort | uniq | wc -l`;
+   debug "number of unique devices: $num_uniq_devs";
    debug "disk space requirements:";
    (( size_per_record = $util_base_sz + ${#WRP_HOST_ADAPTERS[@]} * $util_variable_sz + $ioerr_base_sz
-                        + ${#WRP_DEVICES[@]} * ( $ioerr_variable_sz + $blkiotrace_sz + $zfcpiotrace_sz )
-                        + ( 2 + ${#WRP_DEVICES[@]}) * 8 ));
+                        + $num_uniq_devs * ( $ioerr_variable_sz + $blkiotrace_sz + $zfcpiotrace_sz )
+                        + ( 2 + $num_uniq_devs) * 8 ));
    debug "    size per interval: $size_per_record Bytes";
    (( total_num_records = $WRP_DURATION / $WRP_INTERVAL ));
    debug "    total number of intervals: $total_num_records";
diff --git a/ziomon/ziorep_config b/ziomon/ziorep_config
index 21094bf..de60379 100755
--- a/ziomon/ziorep_config
+++ b/ziomon/ziorep_config
@@ -84,9 +84,10 @@ sub get_sub_ch_data
 		$c_src = catdir($base_dir, S_DIR2, $sub_ch, $adapter);
 		$sub_ch{$adapter}{lic}   = get_line("lic_version");
 		$sub_ch{$adapter}{gen}   = get_line("card_version");
+		$sub_ch{$adapter}{state} = get_line("online") == 1 ? "Online" :
+								     "Offline";
 		$c_src = catdir($base_dir, S_DIR2, $sub_ch);
 		$sub_ch{$adapter}{chpid} = substr(get_line("chpids"), 0, 2);
-		$sub_ch{$adapter}{state} = get_line("port_state");
 	}
 }
 
@@ -220,7 +221,7 @@ sub adapter_report
 	my @adapters = @_;
 
 	foreach my $a (sort keys %sub_ch) {
-		next if (@adapters && "@adapters" !~ /$a/);
+		next if (@adapters && "@adapters" !~ /\b$a\b/);
 		my @out_str;
 		push @out_str, "Host:    $sub_ch{$a}{host}\n";
 		push @out_str, "CHPID:   $sub_ch{$a}{chpid}\n";
@@ -252,11 +253,11 @@ sub device_report
 		      "===============================================\n";
 	}
 	foreach my $hctl (sort keys %devices) {
-		next if (@$adapters && "@$adapters" !~ /$devices{$hctl}{hba_id}/);
-		next if (@$ports && "@$ports" !~ /$devices{$hctl}{wwpn}/);
-		next if (@$luns && "@$luns" !~ /$devices{$hctl}{lun}/);
-		next if (@$s_devs && "@$s_devs" !~ /$devices{$hctl}{dev}/);
-		next if (@$hosts && "@$hosts" !~ /$sub_ch{$devices{$hctl}{hba_id}}{host}/);
+		next if (@$adapters && "@$adapters" !~ /\b$devices{$hctl}{hba_id}\b/);
+		next if (@$ports && "@$ports" !~ /\b$devices{$hctl}{wwpn}\b/);
+		next if (@$luns && "@$luns" !~ /\b$devices{$hctl}{lun}\b/);
+		next if (@$s_devs && "@$s_devs" !~ /\b$devices{$hctl}{dev}\b/);
+		next if (@$hosts && "@$hosts" !~ /\b$sub_ch{$devices{$hctl}{hba_id}}{host}\b/);
 		my @out_str;
 		push @out_str, $devices{$hctl}{hba_id};
 		push @out_str, $devices{$hctl}{wwpn};
@@ -293,10 +294,10 @@ sub mapper_report
 	}
 	foreach my $hctl (sort keys %devices) {
 		next if (! $devices{$hctl}{mp_dev_mm});
-		next if (@$adapters && "@$adapters" !~ /$devices{$hctl}{hba_id}/);
-		next if (@$ports && "@$ports" !~ /$devices{$hctl}{wwpn}/);
-		next if (@$s_devs && "@$s_devs" !~ /$devices{$hctl}{dev}/);
-		next if (@$m_devs && "@$m_devs" !~ /$mapper_dev{$devices{$hctl}{mp_dev_mm}}/);
+		next if (@$adapters && "@$adapters" !~ /\b$devices{$hctl}{hba_id}\b/);
+		next if (@$ports && "@$ports" !~ /\b$devices{$hctl}{wwpn}\b/);
+		next if (@$s_devs && "@$s_devs" !~ /\b$devices{$hctl}{dev}\b/);
+		next if (@$m_devs && "@$m_devs" !~ /\b$mapper_dev{$devices{$hctl}{mp_dev_mm}}\b/);
 		my @line_str;
 		push @line_str, $devices{$hctl}{hba_id};
 		push @line_str, $devices{$hctl}{wwpn};
diff --git a/ziomon/ziorep_traffic.cpp b/ziomon/ziorep_traffic.cpp
index 40cbf47..1461e55 100644
--- a/ziomon/ziorep_traffic.cpp
+++ b/ziomon/ziorep_traffic.cpp
@@ -121,6 +121,7 @@ static int parse_params(int argc, char **argv, struct options *opts)
 	__u32 tmp32;
 	long long unsigned int tmp64;
 	long tmpl;
+	char mychar;
         static struct option long_options[] = {
                 { "version",         no_argument,       NULL, 'v'},
 		{ "help",            no_argument,       NULL, 'h'},
@@ -188,18 +189,22 @@ static int parse_params(int argc, char **argv, struct options *opts)
 			opts->print_summary = true;
 			break;
 		case 'c':
-			rc = sscanf(optarg, "%x", &tmp32);
-			if (rc != 1) {
-				fprintf(stdout, "%s: Could"
+			rc = sscanf(optarg, "%x%c", &tmp32, &mychar);
+			if (rc < 1) {
+				fprintf(stderr, "%s: Could"
 					" not read chpid %s\n", toolname, optarg);
 				return -1;
 			}
+			if (rc > 1) {
+				fprintf(stderr, "%s: %s is not a valid chpid\n", toolname, optarg);
+				return -1;
+			}
 			opts->chpids.push_back(tmp32);
 			break;
 		case 'p':
 			 rc = sscanf(optarg, "0x%Lx", &tmp64);
 			 if (rc != 1) {
-				 fprintf(stdout, "%s: Could"
+				 fprintf(stderr, "%s: Could"
 					 " not read port number %s\n", toolname, optarg);
 				 return -1;
 			 }
@@ -208,7 +213,7 @@ static int parse_params(int argc, char **argv, struct options *opts)
 		case 'l':
 			rc = sscanf(optarg, "0x%Lx", &tmp64);
 			if (rc != 1) {
-				fprintf(stdout, "%s: Could"
+				fprintf(stderr, "%s: Could"
 					" not read lun %s\n", toolname, optarg);
 				return -1;
 			}
@@ -217,11 +222,11 @@ static int parse_params(int argc, char **argv, struct options *opts)
 		case 'u':
 			rc = sscanf(optarg, "0.0.%x", &tmp32);
 			if (rc != 1) {
-				fprintf(stdout, "%s: Could not read bus-ID"
+				fprintf(stderr, "%s: Could not read bus-ID"
 					" %s\n", toolname, optarg);
 				return -1;
 			}
-			opts->wwpns.push_back(tmp32);
+			opts->devnos.push_back(tmp32);
 			break;
 		case 'd':
 			opts->devices.push_back(optarg);
@@ -313,7 +318,7 @@ static int check_opts(struct options *opts, ConfigReader **cfg)
 	for (list<__u32>::const_iterator i = opts->chpids.begin();
 	      i != opts->chpids.end(); ++i) {
 		if (!(*cfg)->verify_chpid(*i)) {
-			fprintf(stdout, "Error: Could not find chpid 0.0.%04x in"
+			fprintf(stderr, "Error: Could not find chpid %x in"
 				" configuration.\n", *i);
 			rc = -2;
 		}
@@ -321,7 +326,7 @@ static int check_opts(struct options *opts, ConfigReader **cfg)
 	for (list<__u32>::const_iterator i = opts->devnos.begin();
 	      i != opts->devnos.end(); ++i) {
 		if (!(*cfg)->verify_devno(*i)) {
-			fprintf(stdout, "Error: Could not find bus-ID 0.0.%04x in"
+			fprintf(stderr, "Error: Could not find bus-ID 0.0.%04x in"
 				" configuration.\n", *i);
 			rc = -3;
 		}
@@ -329,7 +334,7 @@ static int check_opts(struct options *opts, ConfigReader **cfg)
 	for (list<__u64>::const_iterator i = opts->wwpns.begin();
 	      i != opts->wwpns.end(); ++i) {
 		if (!(*cfg)->verify_wwpn(*i)) {
-			fprintf(stdout, "Error: Could not find WWPN %016Lx in"
+			fprintf(stderr, "Error: Could not find WWPN %016Lx in"
 				" configuration.\n", (long long unsigned int)*i);
 			rc = -4;
 		}
@@ -337,7 +342,7 @@ static int check_opts(struct options *opts, ConfigReader **cfg)
 	for (list<__u64>::const_iterator i = opts->luns.begin();
 	      i != opts->luns.end(); ++i) {
 		if (!(*cfg)->verify_lun(*i)) {
-			fprintf(stdout, "Error: Could not find LUN %016Lx in"
+			fprintf(stderr, "Error: Could not find LUN %016Lx in"
 				" configuration.\n", (long long unsigned int)*i);
 			rc = -5;
 		}
@@ -345,7 +350,7 @@ static int check_opts(struct options *opts, ConfigReader **cfg)
 	for (list<const char*>::iterator i = opts->devices.begin();
 	      i != opts->devices.end(); ++i) {
 		if (!(*cfg)->verify_device(*i)) {
-			fprintf(stdout, "Error: Could not find device %s in"
+			fprintf(stderr, "Error: Could not find device %s in"
 				" configuration.\n", *i);
 			rc = -6;
 		}
@@ -353,7 +358,7 @@ static int check_opts(struct options *opts, ConfigReader **cfg)
 	for (list<const char*>::iterator i = opts->mp_devices.begin();
 	      i != opts->mp_devices.end(); ++i) {
 		if (!(*cfg)->verify_mp_device(*i)) {
-			fprintf(stdout, "Error: Could not find multipath"
+			fprintf(stderr, "Error: Could not find multipath"
 				" device %s in configuration.\n", *i);
 			rc = -7;
 		}
diff --git a/ziomon/ziorep_utilization.cpp b/ziomon/ziorep_utilization.cpp
index a036a03..3f57a47 100644
--- a/ziomon/ziorep_utilization.cpp
+++ b/ziomon/ziorep_utilization.cpp
@@ -167,7 +167,7 @@ static int parse_params(int argc, char **argv, struct options *opts)
 		case 'c':
 			rc = sscanf(optarg, "%x", &tmp);
 			if (rc != 1) {
-				fprintf(stdout, "Error: Could not read chpid"
+				fprintf(stderr, "Error: Could not read chpid"
 					" %s\n", optarg);
 				return -1;
 			}
@@ -237,7 +237,7 @@ static int check_opts(struct options *opts, ConfigReader **cfg)
 	for (list<__u32>::const_iterator i = opts->chpids.begin();
 	      i != opts->chpids.end(); ++i) {
 		if (!(*cfg)->verify_chpid(*i)) {
-			fprintf(stdout, "Error: Could not find chpid %x in"
+			fprintf(stderr, "Error: Could not find chpid %x in"
 				" configuration.\n", *i);
 			rc = -2;
 		}
diff --git a/ziomon/ziorep_utils.cpp b/ziomon/ziorep_utils.cpp
index 75a9578..715115e 100644
--- a/ziomon/ziorep_utils.cpp
+++ b/ziomon/ziorep_utils.cpp
@@ -303,8 +303,17 @@ int adjust_timeframe(const char *filename, __u64 *begin, __u64 *end,
 		verbose_msg("using original interval length: %lus\n",
 			    (long unsigned int)*interval);
 	}
-	// now check if the interval is correct
-	if (*interval != UINT32_MAX && *interval % f_hdr.interval_length) {
+	/* the exact frame boundaries don't include the length of the very
+	   first interval, so we have to add one more to our calculations */
+	if (*interval && (*end - *begin + f_hdr.interval_length) % *interval != 0) {
+		// cut off rest in case of user-set interval
+		*end -= (*end - *begin) % *interval + f_hdr.interval_length;
+		t = *end;
+		verbose_msg("    cut off at : %s", ctime(&t));
+	}
+
+	// check if the interval is correct
+	if (*interval % f_hdr.interval_length) {
 		fprintf(stderr, "%s: Data aggregation interval %lu"
 			" is incompatible with source data. Please use"
 			" a multiple of %lu and try again.\n", toolname,
@@ -392,7 +401,7 @@ int print_summary_report(FILE *fp, char *filename, ConfigReader &cfg)
 	rc += fprintf(fp, "Aggregated range: ");
 	if (a_hdr) {
 		rc += fprintf(fp, "%s to ",
-			      print_time_formatted(a_hdr->begin_time));
+			      print_time_formatted(a_hdr->begin_time - f_hdr.interval_length));
 		rc += fprintf(fp, "%s\n",
 			      print_time_formatted(a_hdr->end_time));
 	}
@@ -404,7 +413,7 @@ int print_summary_report(FILE *fp, char *filename, ConfigReader &cfg)
 	a_hdr = NULL;
 
 	rc += fprintf(fp, "Detailed range:   %s to ",
-		      print_time_formatted(f_hdr.begin_time));
+		      print_time_formatted(f_hdr.begin_time - f_hdr.interval_length));
 	rc += fprintf(fp, "%s\n", print_time_formatted(f_hdr.end_time));
 	rc += fprintf(fp, "Interval length:  %d seconds\n",
 		      f_hdr.interval_length);
@@ -446,16 +455,32 @@ int print_summary_report(FILE *fp, char *filename, ConfigReader &cfg)
 	return rc;
 }
 
+/* Calculates seconds since 1970 _without_ caring for daylight
+   savings time (comtrary to mktime() et al).
+   It does not care for leap years and the like, which is OK,
+   since we use it in a very narrow scenario: To calculate any
+   daylight savings time related shifts.
+   Hence: Dont't use if you're not sure what you are doing... */
+static __u64 secs_since_1970(const struct tm *t) {
+	__u64 res = 0;
+	res += t->tm_sec;
+	res += 60 * t->tm_min;
+	res += 3600 * t->tm_hour;
+	res += 86400 * t->tm_yday;
+	res += 86400 * 365 * t->tm_year;
+
+	return res;
+}
+
 
 int get_datetime_val(const char *str, __u64 *tgt)
 {
-	struct tm t;
+	struct tm t, t_old;
 	char *ret;
 
 	// strptime only sets
 	memset(&t, 0, sizeof(struct tm));
 	ret = strptime(str, "%Y-%m-%d %H:%M", &t);
-
 	if (ret == NULL || *ret != '\0') {
 		ret = strptime(str, "%Y-%m-%d %H:%M:%S", &t);
 		if (ret == NULL || *ret != '\0') {
@@ -465,7 +490,13 @@ int get_datetime_val(const char *str, __u64 *tgt)
 			return -1;
 		}
 	}
+	t_old = t;
 	*tgt = mktime(&t);
+	// if daylight savings time applies, 't' has been adjusted,
+	// so we have to correct
+	if (t_old.tm_hour != t.tm_hour)
+		*tgt -= secs_since_1970(&t) - secs_since_1970(&t_old);
+	verbose_msg("datetime value from user after translation: %s", ctime((const time_t *)tgt));
 
 	return 0;
 }
-- 
1.6.0.6