From 986fbedff6f165758fabc74c83b779f397a6d001 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Wed, 4 Jun 2014 16:51:33 +0200 Subject: [PATCH] Accept new naming convention for standard daily data files sadc/sar/sadf: The standard daily data files may now be named saYYYYMMDD instead of saDD, where YYYY stands for the current year, MM for the current month, and DD for the current day. Option -D has been added to sadc to tell it to use saYYYYMMDD instead of saDD. This switch works only if no filename is explicitly given on the command line with sadc. The same option -D has been added to sar. It also tells it to use saYYYYMMDD instead of saDD. This switch works only if no filename is explicitly given on the command line *and* in conjunction with option -o (ie. when sar is used to write data to files). If you use sar to read data from a file without specifying this file's name on the command line (eg. you enter just "sar") then sar will look for the most recent of saDD and saYYYYMMDD and use it. sadf will do the same. If you use sar to write data to files (using its option -o) then it will always use saDD data file unless option -D is used (in which case saYYYYMMDD will be used). This makes it consistent with sadc behavior (and I think it is safer not to let sar decide which file to write to). Signed-off-by: Sebastien GODARD --- sa.h | 7 ++-- sa_common.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++---- sadc.c | 57 ++++++++++++++++++----------- sadf.c | 6 +-- sar.c | 20 +++++++--- 5 files changed, 152 insertions(+), 41 deletions(-) diff --git a/sa.h b/sa.h index e788d46..b6310c6 100644 --- a/sa.h +++ b/sa.h @@ -85,7 +85,7 @@ #define S_F_SEC_EPOCH 0x00000080 #define S_F_HDR_ONLY 0x00000100 #define S_F_FILE_LOCKED 0x00000200 -/* Unused 0x00000400*/ +#define S_F_SA_YYYYMMDD 0x00000400 #define S_F_HORIZONTALLY 0x00000800 #define S_F_COMMENT 0x00001000 #define S_F_PERSIST_NAME 0x00002000 @@ -101,6 +101,7 @@ #define PRINT_SEC_EPOCH(m) (((m) & S_F_SEC_EPOCH) == S_F_SEC_EPOCH) #define DISPLAY_HDR_ONLY(m) (((m) & S_F_HDR_ONLY) == S_F_HDR_ONLY) #define FILE_LOCKED(m) (((m) & S_F_FILE_LOCKED) == S_F_FILE_LOCKED) +#define USE_SA_YYYYMMDD(m) (((m) & S_F_SA_YYYYMMDD) == S_F_SA_YYYYMMDD) #define DISPLAY_HORIZONTALLY(m) (((m) & S_F_HORIZONTALLY) == S_F_HORIZONTALLY) #define DISPLAY_COMMENT(m) (((m) & S_F_COMMENT) == S_F_COMMENT) #define DISPLAY_PERSIST_NAME_S(m) (((m) & S_F_PERSIST_NAME) == S_F_PERSIST_NAME) @@ -808,7 +809,7 @@ extern void extern void allocate_structures(struct activity * []); extern int - check_alt_sa_dir(char *, int); + check_alt_sa_dir(char *, int, int); extern int check_disk_reg(struct activity *, int, int, int); extern void @@ -877,7 +878,7 @@ extern void extern void set_bitmap(unsigned char [], unsigned char, unsigned int); extern void - set_default_file(char *, int); + set_default_file(char *, int, int); extern void set_hdr_rectime(unsigned int, struct tm *, struct file_header *); diff --git a/sa_common.c b/sa_common.c index 363f111..71f4a76 100644 --- a/sa_common.c +++ b/sa_common.c @@ -342,6 +342,60 @@ int parse_timestamp(char *argv[], int *opt, struct tstamp *tse, return decode_timestamp(timestamp, tse); } +/* + *************************************************************************** + * Look for the most recent of saDD and saYYYYMMDD to decide which one to + * use. If neither exists then use saDD by default. + * + * IN: + * @sa_dir Directory where standard daily data files are saved. + * @rectime Structure containing the current date. + * + * OUT: + * @sa_name 0 to use saDD data files, + * 1 to use saYYYYMMDD data files. + *************************************************************************** + */ +void guess_sa_name(char *sa_dir, struct tm *rectime, int *sa_name) +{ + char filename[MAX_FILE_LEN]; + struct stat sb; + time_t sa_mtime; + + /* Use saDD by default */ + *sa_name = 0; + + /* Look for saYYYYMMDD */ + snprintf(filename, MAX_FILE_LEN, + "%s/sa%04d%02d%02d", sa_dir, + rectime->tm_year + 1900, + rectime->tm_mon + 1, + rectime->tm_mday); + filename[MAX_FILE_LEN - 1] = '\0'; + + if (stat(filename, &sb) < 0) + /* Cannot find or access saYYYYMMDD, so use saDD */ + return; + sa_mtime = sb.st_mtime; + + /* Look for saDD */ + snprintf(filename, MAX_FILE_LEN, + "%s/sa%02d", sa_dir, + rectime->tm_mday); + filename[MAX_FILE_LEN - 1] = '\0'; + + if (stat(filename, &sb) < 0) { + /* Cannot find or access saDD, so use saYYYYMMDD */ + *sa_name = 1; + return; + } + + if (sa_mtime > sb.st_mtime) { + /* saYYYYMMDD is more recent than saDD, so use it */ + *sa_name = 1; + } +} + /* *************************************************************************** * Set current daily data file name. @@ -350,12 +404,16 @@ int parse_timestamp(char *argv[], int *opt, struct tstamp *tse, * @datafile If not an empty string then this is the alternate directory * location where daily data files will be saved. * @d_off Day offset (number of days to go back in the past). + * @sa_name 0 for saDD data files, + * 1 for saYYYYMMDD data files, + * -1 if unknown. In this case, will look for the most recent + * of saDD and saYYYYMMDD and use it. * * OUT: * @datafile Name of daily data file. *************************************************************************** */ -void set_default_file(char *datafile, int d_off) +void set_default_file(char *datafile, int d_off, int sa_name) { char sa_dir[MAX_FILE_LEN]; struct tm rectime; @@ -370,8 +428,28 @@ void set_default_file(char *datafile, int d_off) sa_dir[MAX_FILE_LEN - 1] = '\0'; get_time(&rectime, d_off); - snprintf(datafile, MAX_FILE_LEN, - "%s/sa%02d", sa_dir, rectime.tm_mday); + if (sa_name < 0) { + /* + * Look for the most recent of saDD and saYYYYMMDD + * and use it. If neither exists then use saDD. + * sa_name is set accordingly. + */ + guess_sa_name(sa_dir, &rectime, &sa_name); + } + if (sa_name) { + /* Using saYYYYMMDD data files */ + snprintf(datafile, MAX_FILE_LEN, + "%s/sa%04d%02d%02d", sa_dir, + rectime.tm_year + 1900, + rectime.tm_mon + 1, + rectime.tm_mday); + } + else { + /* Using saDD data files */ + snprintf(datafile, MAX_FILE_LEN, + "%s/sa%02d", sa_dir, + rectime.tm_mday); + } datafile[MAX_FILE_LEN - 1] = '\0'; default_file_used = TRUE; } @@ -384,6 +462,11 @@ void set_default_file(char *datafile, int d_off) * IN: * @datafile Name of the daily data file. May be a directory. * @d_off Day offset (number of days to go back in the past). + * @sa_name 0 for saDD data files, + * 1 for saYYYYMMDD data files, + * -1 if unknown. In this case, will look for the most recent + * of saDD and saYYYYMMDD and use it. + * * * OUT: * @datafile Name of the daily data file. This is now a plain file, not @@ -393,15 +476,19 @@ void set_default_file(char *datafile, int d_off) * 1 if @datafile was a directory, and 0 otherwise. *************************************************************************** */ -int check_alt_sa_dir(char *datafile, int d_off) +int check_alt_sa_dir(char *datafile, int d_off, int sa_name) { struct stat sb; - stat(datafile, &sb); + if (stat(datafile, &sb) == 0) { if (S_ISDIR(sb.st_mode)) { - /* This is a directory: So append the default file name to it */ - set_default_file(datafile, d_off); - return 1; + /* + * This is a directory: So append + * the default file name to it. + */ + set_default_file(datafile, d_off, sa_name); + return 1; + } } return 0; diff --git a/sadc.c b/sadc.c index 8d3b87d..e7d0b76 100644 --- a/sadc.c +++ b/sadc.c @@ -88,7 +88,7 @@ void usage(char *progname) progname); fprintf(stderr, _("Options are:\n" - "[ -C ] [ -F ] [ -L ] [ -V ]\n" + "[ -C ] [ -D ] [ -F ] [ -L ] [ -V ]\n" "[ -S { INT | DISK | IPV6 | POWER | SNMP | XDISK | ALL | XALL } ]\n")); exit(1); } @@ -1177,7 +1177,7 @@ void rw_sa_stat_loop(long count, int stdfd, int ofd, char ofile[], if (WANT_SA_ROTAT(flags)) { /* The user specified '-' as the filename to use */ strcpy(new_ofile, sa_dir); - set_default_file(new_ofile, 0); + set_default_file(new_ofile, 0, USE_SA_YYYYMMDD(flags)); if (strcmp(ofile, new_ofile)) { do_sa_rotat = TRUE; @@ -1236,6 +1236,10 @@ int main(int argc, char **argv) } } + else if (!strcmp(argv[opt], "-D")) { + flags |= S_F_SA_YYYYMMDD; + } + else if (!strcmp(argv[opt], "-F")) { flags |= S_F_FORCE_FILE; } @@ -1267,14 +1271,13 @@ int main(int argc, char **argv) } else if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) { - if (ofile[0]) { + if (ofile[0] || WANT_SA_ROTAT(flags)) { /* Outfile already specified */ usage(argv[0]); } stdfd = -1; /* Don't write to STDOUT */ if (!strcmp(argv[opt], "-")) { /* File name set to '-' */ - set_default_file(ofile, 0); flags |= S_F_SA_ROTAT; } else if (!strncmp(argv[opt], "-", 1)) { @@ -1285,24 +1288,6 @@ int main(int argc, char **argv) /* Write data to file */ strncpy(ofile, argv[opt], MAX_FILE_LEN); ofile[MAX_FILE_LEN - 1] = '\0'; - /* - * Should ofile be a directory, it will be the alternate - * location for sa files. So save it. - */ - strcpy(sa_dir, ofile); - /* Check if this is an alternate directory for sa files */ - if (check_alt_sa_dir(ofile, 0)) { - /* - * Yes, it was a directory. - * ofile now contains the full path to current - * standard daily data file. - */ - flags |= S_F_SA_ROTAT; - } - else { - /* No: So we can clear sa_dir */ - sa_dir[0] = '\0'; - } } } @@ -1328,6 +1313,34 @@ int main(int argc, char **argv) } } + /* Process file entered on the command line */ + if (WANT_SA_ROTAT(flags)) { + /* File name set to '-' */ + set_default_file(ofile, 0, USE_SA_YYYYMMDD(flags)); + } + else if (ofile[0]) { + /* + * A file (or directory) has been explicitly entered + * on the command line. + * Should ofile be a directory, it will be the alternate + * location for sa files. So save it. + */ + strcpy(sa_dir, ofile); + /* Check if this is an alternate directory for sa files */ + if (check_alt_sa_dir(ofile, 0, USE_SA_YYYYMMDD(flags))) { + /* + * Yes, it was a directory. + * ofile now contains the full path to current + * standard daily data file. + */ + flags |= S_F_SA_ROTAT; + } + else { + /* No: So we can clear sa_dir */ + sa_dir[0] = '\0'; + } + } + /* * If option -z used, write to STDOUT even if a filename * has been entered on the command line. diff --git a/sadf.c b/sadf.c index f35ea93..133bf31 100644 --- a/sadf.c +++ b/sadf.c @@ -1649,7 +1649,7 @@ int main(int argc, char **argv) } if (!strcmp(argv[opt], "-")) { /* File name set to '-' */ - set_default_file(dfile, 0); + set_default_file(dfile, 0, -1); opt++; } else if (!strncmp(argv[opt], "-", 1)) { @@ -1661,7 +1661,7 @@ int main(int argc, char **argv) strncpy(dfile, argv[opt++], MAX_FILE_LEN); dfile[MAX_FILE_LEN - 1] = '\0'; /* Check if this is an alternate directory for sa files */ - check_alt_sa_dir(dfile, 0); + check_alt_sa_dir(dfile, 0, -1); } } @@ -1697,7 +1697,7 @@ int main(int argc, char **argv) /* sadf reads current daily data file by default */ if (!dfile[0]) { - set_default_file(dfile, 0); + set_default_file(dfile, 0, -1); } if (tm_start.use && tm_end.use && (tm_end.tm_hour < tm_start.tm_hour)) { diff --git a/sar.c b/sar.c index 7ab8b5a..0b4d729 100644 --- a/sar.c +++ b/sar.c @@ -107,8 +107,8 @@ void usage(char *progname) { print_usage_title(stderr, progname); fprintf(stderr, _("Options are:\n" - "[ -A ] [ -B ] [ -b ] [ -C ] [ -d ] [ -F ] [ -H ] [ -h ] [ -p ] [ -q ] [ -R ]\n" - "[ -r ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ] [ -v ] [ -W ] [ -w ] [ -y ]\n" + "[ -A ] [ -B ] [ -b ] [ -C ] [ -D ] [ -d ] [ -F ] [ -H ] [ -h ] [ -p ] [ -q ]\n" + "[ -R ] [ -r ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ] [ -v ] [ -W ] [ -w ] [ -y ]\n" "[ -I { [,...] | SUM | ALL | XALL } ] [ -P { [,...] | ALL } ]\n" "[ -m { [,...] | ALL } ] [ -n { [,...] | ALL } ]\n" "[ -j { ID | LABEL | PATH | UUID | ... } ]\n" @@ -1176,6 +1176,12 @@ int main(int argc, char **argv) } } + else if (!strcmp(argv[opt], "-D")) { + /* Option to tell sar to write to saYYYYMMDD data files */ + flags |= S_F_SA_YYYYMMDD; + opt++; + } + else if (!strcmp(argv[opt], "-P")) { /* Parse -P option */ if (parse_sa_P_opt(argv, &opt, &flags, act)) { @@ -1210,10 +1216,10 @@ int main(int argc, char **argv) strncpy(from_file, argv[opt++], MAX_FILE_LEN); from_file[MAX_FILE_LEN - 1] = '\0'; /* Check if this is an alternate directory for sa files */ - check_alt_sa_dir(from_file, day_offset); + check_alt_sa_dir(from_file, day_offset, -1); } else { - set_default_file(from_file, day_offset); + set_default_file(from_file, day_offset, -1); } } @@ -1320,7 +1326,7 @@ int main(int argc, char **argv) /* 'sar' is equivalent to 'sar -f' */ if ((argc == 1) || ((interval < 0) && !from_file[0] && !to_file[0])) { - set_default_file(from_file, day_offset); + set_default_file(from_file, day_offset, -1); } if (tm_start.use && tm_end.use && (tm_end.tm_hour < tm_start.tm_hour)) { @@ -1433,6 +1439,10 @@ int main(int argc, char **argv) /* Writing data to a file (option -o) */ if (to_file[0]) { + /* Set option -D if entered */ + if (USE_SA_YYYYMMDD(flags)) { + salloc(args_idx++, "-D"); + } /* Collect all possible activities (option -S XALL for sadc) */ salloc(args_idx++, "-S"); salloc(args_idx++, K_XALL); -- 2.40.0