summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2015-05-25 16:13:07 +0200
committerPeter Rajnoha <prajnoha@redhat.com>2015-06-29 14:30:35 +0200
commit125cd06698bc1c52b812faa1686988b92cc2e192 (patch)
tree3e63540df7887c1fd3713a21545c3da321dab42d
parent6f793d34ca8993d1e70df58340d7c1897b368a09 (diff)
downloadlvm2-125cd06698bc1c52b812faa1686988b92cc2e192.tar.gz
conf: make time format configurable
Make it possible to define format for time that is displayed. The way the format is defined is equal to the way that is used for strftime function, although not all formatting options as used in strftime are available for LVM2 - the set is restricted (e.g. we do not allow newline to be printed). The lvm.conf comments contain the whole list that LVM2 accepts for time format together with brief description (copied from strftime man page). For example: (defaults used - the format is the same as used before this patch) $ lvs -o+time vg/lvol0 vg/lvol1 LV VG Attr LSize Time lvol0 vg -wi-a----- 4.00m 2015-06-25 16:18:34 +0200 lvol1 vg -wi-a----- 4.00m 2015-06-29 09:17:11 +0200 (using 'time_format = "@%s"' in lvm.conf - number of seconds since the Epoch) $ lvs -o+time vg/lvol0 vg/lvol1 LV VG Attr LSize Time lvol0 vg -wi-a----- 4.00m @1435241914 lvol1 vg -wi-a----- 4.00m @1435562231
-rw-r--r--WHATS_NEW1
-rw-r--r--conf/example.conf.in73
-rw-r--r--lib/commands/toolcontext.c52
-rw-r--r--lib/commands/toolcontext.h2
-rw-r--r--lib/config/config_settings.h73
-rw-r--r--lib/config/defaults.h1
-rw-r--r--lib/display/display.c2
-rw-r--r--lib/metadata/lv.c7
-rw-r--r--lib/metadata/lv.h2
-rw-r--r--lib/report/properties.c2
-rw-r--r--lib/report/report.c2
11 files changed, 209 insertions, 8 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 813eb5eca..9a7ebe109 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.123 -
=================================
+ Add report/time_format lvm.conf option to define time format for report.
Fix makefile shell compare == when building lvmetad lvmpolld (2.02.120).
Add --type full to lvmconfig for full configuration tree view.
Add undocumented environment variables to lvm man page. (2.02.119)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 34335083a..41b9702cd 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1411,6 +1411,79 @@ activation {
# value could not be determined).
# binary_values_as_numeric = 0
+ # Configuration option report/time_format.
+ # Set time format for fields reporting time values.
+ # Format specification is a string which may contain special character
+ # sequences and ordinary character sequences. Ordinary character sequences
+ # are copied verbatim. Each special character sequence is introduced by '%'
+ # character and such sequence is then substitued with a value as described below:
+ # %a The abbreviated name of the day of the week according to the
+ # current locale.
+ # %A The full name of the day of the week according to the current locale.
+ # %b The abbreviated month name according to the current locale.
+ # %B The full month name according to the current locale.
+ # %c The preferred date and time representation for the current locale. (alt E)
+ # %C The century number (year/100) as a 2-digit integer. (alt E)
+ # %d The day of the month as a decimal number (range 01 to 31). (alt O)
+ # %D Equivalent to %m/%d/%y. (For Americans only. Americans should
+ # note that in other countries%d/%m/%y is rather common. This means
+ # that in international context this format is ambiguous and should not
+ # be used.
+ # %e Like %d, the day of the month as a decimal number, but a leading zero
+ # is replaced by a space. (alt O)
+ # %E Modifier: use alternative local-dependent representation if available.
+ # %F Equivalent to %Y-%m-%d (the ISO 8601 date format).
+ # %G The ISO 8601 week-based year with century as adecimal number. The 4-digit
+ # year corresponding to the ISO week number (see %V). This has the same
+ # format and value as %Y, except that if the ISO week number belongs to
+ # the previous or next year, that year is used instead.
+ # %g Like %G, but without century, that is, with a 2-digit year (00-99).
+ # %h Equivalent to %b.
+ # %H The hour as a decimal number using a 24-hour clock (range 00 to 23). (alt O)
+ # %I The hour as a decimal number using a 12-hour clock (range 01 to 12). (alt O)
+ # %j The day of the year as a decimal number (range 001 to 366).
+ # %k The hour (24-hour clock) as a decimal number (range 0 to 23);
+ # single digits are preceded by a blank. (See also %H.)
+ # %l The hour (12-hour clock) as a decimal number (range 1 to 12);
+ # single digits are preceded by a blank. (See also %I.)
+ # %m The month as a decimal number (range 01 to 12). (alt O)
+ # %M The minute as a decimal number (range 00 to 59). (alt O)
+ # %O Modifier: use alternative numeric symbols.
+ # %p Either "AM" or "PM" according to the given time value,
+ # or the corresponding strings for the current locale. Noon is
+ # treated as "PM" and midnight as "AM".
+ # %P Like %p but in lowercase: "am" or "pm" or a corresponding
+ # string for the current locale.
+ # %r The time in a.m. or p.m. notation. In the POSIX locale this is
+ # equivalent to %I:%M:%S %p.
+ # %R The time in 24-hour notation (%H:%M). For a version including
+ # the seconds, see %T below.
+ # %s The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC)
+ # %S The second as a decimal number (range 00 to 60).
+ # (The range is up to 60 to allow for occasional leap seconds.) (alt O)
+ # %t A tab character.
+ # %T The time in 24-hour notation (%H:%M:%S).
+ # %u The day of the week as a decimal, range 1 to 7, Monday being 1.
+ # See also %w. (alt O)
+ # %U The week number of the current year as a decimal number,
+ # range 00 to 53, starting with the first Sunday as the first
+ # day of week 01. See also %V and %W. (alt O)
+ # %V The ISO 8601 week number of the current year as a decimal number,
+ # range 01 to 53, where week 1 is the first week that has at least 4 days
+ # in the new year. See also %U and %W. (alt O)
+ # %w The day of the week as a decimal, range 0 to 6, Sunday being 0.
+ # See also %u. (alt O)
+ # %W The week number of the current year as a decimal number, range 00 to 53,
+ # starting with the first Monday as the first day of week 01. (alt O)
+ # %x The preferred date representation for the current locale without the time. (alt E)
+ # %X The preferred time representation for the current locale without the date. (alt E)
+ # %y The year as a decimal number without a century (range 00 to 99). (alt E, alt O)
+ # %Y The year as a decimal number including the century. (alt E)
+ # %z The +hhmm or -hhmm numeric timezone (that is, the hour and minute
+ # offset from UTC).%Z The timezone name or abbreviation.
+ # %% A literal '%' character.
+ # time_format = "%Y-%m-%d %T %z"
+
# Configuration option report/devtypes_sort.
# List of columns to sort by when reporting 'lvm devtypes' command.
# See 'lvm devtypes -o help' for the list of possible fields.
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 47aa209d5..0d243f27f 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -413,6 +413,57 @@ static int _check_config(struct cmd_context *cmd)
return 1;
}
+static const char *_set_time_format(struct cmd_context *cmd)
+{
+ /* Compared to strftime, we do not allow "newline" character - the %n in format. */
+ static const char *allowed_format_chars = "aAbBcCdDeFGghHIjklmMpPrRsStTuUVwWxXyYzZ%";
+ static const char *allowed_alternative_format_chars_e = "cCxXyY";
+ static const char *allowed_alternative_format_chars_o = "deHImMSuUVwWy";
+ static const char *chars_to_check;
+ const char *tf = find_config_tree_str(cmd, report_time_format_CFG, NULL);
+ const char *p_fmt;
+ size_t i;
+ char c;
+
+ if (!*tf) {
+ log_error("Configured time format is empty string.");
+ goto bad;
+ } else {
+ p_fmt = tf;
+ while ((c = *p_fmt)) {
+ if (c == '%') {
+ c = *++p_fmt;
+ if (c == 'E') {
+ c = *++p_fmt;
+ chars_to_check = allowed_alternative_format_chars_e;
+ } else if (c == 'O') {
+ c = *++p_fmt;
+ chars_to_check = allowed_alternative_format_chars_o;
+ } else
+ chars_to_check = allowed_format_chars;
+
+ for (i = 0; chars_to_check[i]; i++) {
+ if (c == allowed_format_chars[i])
+ break;
+ }
+ if (!allowed_format_chars[i])
+ goto_bad;
+ }
+ else if (isprint(c))
+ p_fmt++;
+ else {
+ log_error("Configured time format contains non-printable characters.");
+ goto bad;
+ }
+ }
+ }
+
+ return tf;
+bad:
+ log_error("Incorrect time format specified. Using default time format instead.");
+ return DEFAULT_TIME_FORMAT;
+}
+
int process_profilable_config(struct cmd_context *cmd)
{
if (!(cmd->default_settings.unit_factor =
@@ -426,6 +477,7 @@ int process_profilable_config(struct cmd_context *cmd)
cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
cmd->report_list_item_separator = find_config_tree_str(cmd, report_list_item_separator_CFG, NULL);
+ cmd->time_format = _set_time_format(cmd);
return 1;
}
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 66bea5fc9..46d83b3c0 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -95,6 +95,8 @@ struct cmd_context {
unsigned ignore_clustered_vgs:1;
unsigned threaded:1; /* Set if running within a thread e.g. clvmd */
+ const char *time_format;
+
unsigned independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
unsigned unknown_system_id:1;
unsigned include_foreign_vgs:1;
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 2c5e2f8c9..ac68906ee 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -1357,6 +1357,79 @@ cfg(report_binary_values_as_numeric_CFG, "binary_values_as_numeric", report_CFG_
"(not counting the 'unknown' value which denotes that the\n"
"value could not be determined).\n")
+cfg(report_time_format_CFG, "time_format", report_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_TIME_FORMAT, vsn(2, 2, 121), NULL, 0, NULL,
+ "Set time format for fields reporting time values.\n"
+ "Format specification is a string which may contain special character\n"
+ "sequences and ordinary character sequences. Ordinary character sequences\n"
+ "are copied verbatim. Each special character sequence is introduced by \'%\'\n"
+ "character and such sequence is then substitued with a value as described below:\n"
+ "\%a The abbreviated name of the day of the week according to the\n"
+ " current locale.\n"
+ "\%A The full name of the day of the week according to the current locale.\n"
+ "\%b The abbreviated month name according to the current locale.\n"
+ "\%B The full month name according to the current locale.\n"
+ "\%c The preferred date and time representation for the current locale. (alt E)\n"
+ "\%C The century number (year/100) as a 2-digit integer. (alt E)\n"
+ "\%d The day of the month as a decimal number (range 01 to 31). (alt O)\n"
+ "\%D Equivalent to \%m/\%d/\%y. (For Americans only. Americans should\n"
+ " note that in other countries\%d/\%m/\%y is rather common. This means\n"
+ " that in international context this format is ambiguous and should not\n"
+ " be used.\n"
+ "\%e Like \%d, the day of the month as a decimal number, but a leading zero\n"
+ " is replaced by a space. (alt O)\n"
+ "\%E Modifier: use alternative local-dependent representation if available.\n"
+ "\%F Equivalent to \%Y-\%m-\%d (the ISO 8601 date format).\n"
+ "\%G The ISO 8601 week-based year with century as adecimal number. The 4-digit\n"
+ " year corresponding to the ISO week number (see \%V). This has the same\n"
+ " format and value as \%Y, except that if the ISO week number belongs to\n"
+ " the previous or next year, that year is used instead.\n"
+ "\%g Like \%G, but without century, that is, with a 2-digit year (00-99).\n"
+ "\%h Equivalent to \%b.\n"
+ "\%H The hour as a decimal number using a 24-hour clock (range 00 to 23). (alt O)\n"
+ "\%I The hour as a decimal number using a 12-hour clock (range 01 to 12). (alt O)\n"
+ "\%j The day of the year as a decimal number (range 001 to 366).\n"
+ "\%k The hour (24-hour clock) as a decimal number (range 0 to 23);\n"
+ " single digits are preceded by a blank. (See also \%H.)\n"
+ "\%l The hour (12-hour clock) as a decimal number (range 1 to 12);\n"
+ " single digits are preceded by a blank. (See also \%I.)\n"
+ "\%m The month as a decimal number (range 01 to 12). (alt O)\n"
+ "\%M The minute as a decimal number (range 00 to 59). (alt O)\n"
+ "\%O Modifier: use alternative numeric symbols.\n"
+ "\%p Either \"AM\" or \"PM\" according to the given time value,\n"
+ " or the corresponding strings for the current locale. Noon is\n"
+ " treated as \"PM\" and midnight as \"AM\".\n"
+ "\%P Like \%p but in lowercase: \"am\" or \"pm\" or a corresponding\n"
+ " string for the current locale.\n"
+ "\%r The time in a.m. or p.m. notation. In the POSIX locale this is\n"
+ " equivalent to \%I:\%M:\%S \%p.\n"
+ "\%R The time in 24-hour notation (\%H:\%M). For a version including\n"
+ " the seconds, see \%T below.\n"
+ "\%s The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC)\n"
+ "\%S The second as a decimal number (range 00 to 60).\n"
+ " (The range is up to 60 to allow for occasional leap seconds.) (alt O)\n"
+ "\%t A tab character.\n"
+ "\%T The time in 24-hour notation (\%H:\%M:\%S).\n"
+ "\%u The day of the week as a decimal, range 1 to 7, Monday being 1.\n"
+ " See also \%w. (alt O)\n"
+ "\%U The week number of the current year as a decimal number,\n"
+ " range 00 to 53, starting with the first Sunday as the first\n"
+ " day of week 01. See also \%V and \%W. (alt O)\n"
+ "\%V The ISO 8601 week number of the current year as a decimal number,\n"
+ " range 01 to 53, where week 1 is the first week that has at least 4 days\n"
+ " in the new year. See also \%U and \%W. (alt O)\n"
+ "\%w The day of the week as a decimal, range 0 to 6, Sunday being 0.\n"
+ " See also \%u. (alt O)\n"
+ "\%W The week number of the current year as a decimal number, range 00 to 53,\n"
+ " starting with the first Monday as the first day of week 01. (alt O)\n"
+ "\%x The preferred date representation for the current locale without the time. (alt E)\n"
+ "\%X The preferred time representation for the current locale without the date. (alt E)\n"
+ "\%y The year as a decimal number without a century (range 00 to 99). (alt E, alt O)\n"
+ "\%Y The year as a decimal number including the century. (alt E)\n"
+ "\%z The +hhmm or -hhmm numeric timezone (that is, the hour and minute\n"
+ " offset from UTC)."
+ "\%Z The timezone name or abbreviation.\n"
+ "\%\% A literal '\%' character.\n")
+
cfg(report_devtypes_sort_CFG, "devtypes_sort", report_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DEVTYPES_SORT, vsn(2, 2, 101), NULL, 0, NULL,
"List of columns to sort by when reporting 'lvm devtypes' command.\n"
"See 'lvm devtypes -o help' for the list of possible fields.\n")
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index d764ec9a3..3745639fe 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -197,6 +197,7 @@
#define DEFAULT_REP_QUOTED 1
#define DEFAULT_REP_SEPARATOR " "
#define DEFAULT_REP_LIST_ITEM_SEPARATOR ","
+#define DEFAULT_TIME_FORMAT "%Y-%m-%d %T %z"
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
diff --git a/lib/display/display.c b/lib/display/display.c
index 8f075d910..059bc8f2a 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -489,7 +489,7 @@ int lvdisplay_full(struct cmd_context *cmd,
log_print("LV UUID %s", uuid);
log_print("LV Write Access %s", access_str);
log_print("LV Creation host, time %s, %s",
- lv_host_dup(cmd->mem, lv), lv_time_dup(cmd->mem, lv));
+ lv_host_dup(cmd->mem, lv), lv_time_dup(cmd->mem, lv, 1));
if (lv_is_origin(lv)) {
log_print("LV snapshot status source of");
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 9a99c8d1c..2a87edd06 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -873,17 +873,16 @@ int lv_set_creation(struct logical_volume *lv,
return 1;
}
-char *lv_time_dup(struct dm_pool *mem, const struct logical_volume *lv)
+char *lv_time_dup(struct dm_pool *mem, const struct logical_volume *lv, int iso_mode)
{
char buffer[50];
struct tm *local_tm;
time_t ts = (time_t)lv->timestamp;
+ const char *format = iso_mode ? DEFAULT_TIME_FORMAT : lv->vg->cmd->time_format;
if (!ts ||
!(local_tm = localtime(&ts)) ||
- /* FIXME: make this lvm.conf configurable */
- !strftime(buffer, sizeof(buffer),
- "%Y-%m-%d %T %z", local_tm))
+ !strftime(buffer, sizeof(buffer), format, local_tm))
buffer[0] = 0;
return dm_pool_strdup(mem, buffer);
diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h
index 44750851a..f7bbb1eda 100644
--- a/lib/metadata/lv.h
+++ b/lib/metadata/lv.h
@@ -91,7 +91,7 @@ char *lvseg_monitor_dup(struct dm_pool *mem, const struct lv_segment *seg);
char *lvseg_tags_dup(const struct lv_segment *seg);
char *lvseg_devices(struct dm_pool *mem, const struct lv_segment *seg);
char *lvseg_seg_pe_ranges(struct dm_pool *mem, const struct lv_segment *seg);
-char *lv_time_dup(struct dm_pool *mem, const struct logical_volume *lv);
+char *lv_time_dup(struct dm_pool *mem, const struct logical_volume *lv, int iso_mode);
char *lv_host_dup(struct dm_pool *mem, const struct logical_volume *lv);
int lv_set_creation(struct logical_volume *lv,
const char *hostname, uint64_t timestamp);
diff --git a/lib/report/properties.c b/lib/report/properties.c
index b0a91a7da..5cd3c4dd9 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -342,7 +342,7 @@ GET_LV_NUM_PROPERTY_FN(metadata_percent, _metadata_percent(lv))
#define _metadata_percent_set prop_not_implemented_set
GET_LV_NUM_PROPERTY_FN(lv_metadata_size, lv_metadata_size(lv) * SECTOR_SIZE)
#define _lv_metadata_size_set prop_not_implemented_set
-GET_LV_STR_PROPERTY_FN(lv_time, lv_time_dup(lv->vg->vgmem, lv))
+GET_LV_STR_PROPERTY_FN(lv_time, lv_time_dup(lv->vg->vgmem, lv, 0))
#define _lv_time_set prop_not_implemented_set
GET_LV_STR_PROPERTY_FN(lv_host, lv_host_dup(lv->vg->vgmem, lv))
#define _lv_host_set prop_not_implemented_set
diff --git a/lib/report/report.c b/lib/report/report.c
index a1076690a..30b37674a 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1474,7 +1474,7 @@ static int _lvtime_disp(struct dm_report *rh, struct dm_pool *mem,
char *repstr;
uint64_t *sortval;
- if (!(repstr = lv_time_dup(mem, lv)) ||
+ if (!(repstr = lv_time_dup(mem, lv, 0)) ||
!(sortval = dm_pool_alloc(mem, sizeof(uint64_t)))) {
log_error("Failed to allocate buffer for time.");
return 0;