allocate_bitmaps(struct activity * []);
extern void
allocate_structures(struct activity * []);
+extern int
+ check_alt_sa_dir(char *, int);
extern int
check_disk_reg(struct activity *, int, int, int);
extern void
extern void
set_bitmap(unsigned char [], unsigned char, unsigned int);
extern void
- set_default_file(struct tm *, char *, int);
+ set_default_file(char *, int);
extern void
set_hdr_rectime(unsigned int, struct tm *, struct file_header *);
#include <fcntl.h>
#include <libgen.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/ioctl.h>
#include "sa.h"
* Set current daily data file name.
*
* IN:
+ * @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).
*
* OUT:
- * @rectime Current date and time.
* @datafile Name of daily data file.
***************************************************************************
*/
-void set_default_file(struct tm *rectime, char *datafile, int d_off)
+void set_default_file(char *datafile, int d_off)
{
- get_time(rectime, d_off);
+ char sa_dir[MAX_FILE_LEN];
+ struct tm rectime;
+
+ /* Set directory where daily data files will be saved */
+ if (datafile[0]) {
+ strncpy(sa_dir, datafile, MAX_FILE_LEN);
+ }
+ else {
+ strncpy(sa_dir, SA_DIR, MAX_FILE_LEN);
+ }
+ 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);
+ "%s/sa%02d", sa_dir, rectime.tm_mday);
datafile[MAX_FILE_LEN - 1] = '\0';
default_file_used = TRUE;
}
+/*
+ ***************************************************************************
+ * Check data file type. If it is a directory then this is the alternate
+ * location where daily data files will be saved.
+ *
+ * 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).
+ *
+ * OUT:
+ * @datafile Name of the daily data file. This is now a plain file, not
+ * a directory.
+ *
+ * RETURNS:
+ * 1 if @datafile was a directory, and 0 otherwise.
+ ***************************************************************************
+ */
+int check_alt_sa_dir(char *datafile, int d_off)
+{
+ struct stat sb;
+
+ stat(datafile, &sb);
+ 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;
+ }
+
+ return 0;
+}
+
/*
***************************************************************************
* Set interval value.
* Main loop: Read stats from the relevant sources and display them.
*
* IN:
- * @count Number of lines of stats to display.
- * @rectime Current date and time.
- * @stdfd Stdout file descriptor.
- * @ofd Output file descriptor.
- * @ofile Name of output file.
+ * @count Number of lines of stats to display.
+ * @stdfd Stdout file descriptor.
+ * @ofd Output file descriptor.
+ * @ofile Name of output file.
+ * @sa_dir If not an empty string, contains the alternate location of
+ * daily data files.
***************************************************************************
*/
-void rw_sa_stat_loop(long count, struct tm *rectime, int stdfd, int ofd,
- char ofile[])
+void rw_sa_stat_loop(long count, int stdfd, int ofd, char ofile[],
+ char sa_dir[])
{
int do_sa_rotat = 0;
unsigned int save_flags;
char new_ofile[MAX_FILE_LEN];
-
- new_ofile[0] = '\0';
+ struct tm rectime;
/* Set a handler for SIGINT */
memset(&int_act, 0, sizeof(int_act));
reset_stats();
/* Save time */
- record_hdr.ust_time = get_time(rectime, 0);
- record_hdr.hour = rectime->tm_hour;
- record_hdr.minute = rectime->tm_min;
- record_hdr.second = rectime->tm_sec;
+ record_hdr.ust_time = get_time(&rectime, 0);
+ record_hdr.hour = rectime.tm_hour;
+ record_hdr.minute = rectime.tm_min;
+ record_hdr.second = rectime.tm_sec;
/* Set record type */
if (do_sa_rotat) {
/* Rotate activity file if necessary */
if (WANT_SA_ROTAT(flags)) {
/* The user specified '-' as the filename to use */
- set_default_file(rectime, new_ofile, 0);
+ strcpy(new_ofile, sa_dir);
+ set_default_file(new_ofile, 0);
if (strcmp(ofile, new_ofile)) {
do_sa_rotat = TRUE;
int main(int argc, char **argv)
{
int opt = 0;
- char ofile[MAX_FILE_LEN];
- struct tm rectime;
+ char ofile[MAX_FILE_LEN], sa_dir[MAX_FILE_LEN];
int stdfd = 0, ofd = -1;
int restart_mark;
long count = 0;
/* Compute page shift in kB */
get_kb_shift();
- ofile[0] = comment[0] = '\0';
+ ofile[0] = sa_dir[0] = comment[0] = '\0';
#ifdef HAVE_SENSORS
/* Initialize sensors, let it use the default cfg file */
}
else if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) {
- if (!ofile[0]) {
- stdfd = -1; /* Don't write to STDOUT */
- if (!strcmp(argv[opt], "-")) {
- /* File name set to '-' */
- set_default_file(&rectime, ofile, 0);
+ if (ofile[0]) {
+ /* 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)) {
+ /* Bad option */
+ usage(argv[0]);
+ }
+ else {
+ /* 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 if (!strncmp(argv[opt], "-", 1)) {
- /* Bad option */
- usage(argv[0]);
- }
else {
- /* Write data to file */
- strncpy(ofile, argv[opt], MAX_FILE_LEN);
- ofile[MAX_FILE_LEN - 1] = '\0';
+ /* No: So we can clear sa_dir */
+ sa_dir[0] = '\0';
}
}
- else {
- /* Outfile already specified */
- usage(argv[0]);
- }
}
else if (!interval) {
alarm(interval);
/* Main loop */
- rw_sa_stat_loop(count, &rectime, stdfd, ofd, ofile);
+ rw_sa_stat_loop(count, stdfd, ofd, ofile, sa_dir);
#ifdef HAVE_SENSORS
/* Cleanup sensors */
int opt = 1, sar_options = 0;
int i, rc;
char dfile[MAX_FILE_LEN];
- struct tm rectime;
/* Get HZ */
get_HZ();
/* Get data file name */
else if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) {
- if (!dfile[0]) {
- if (!strcmp(argv[opt], "-")) {
- /* File name set to '-' */
- set_default_file(&rectime, dfile, 0);
- opt++;
- }
- else if (!strncmp(argv[opt], "-", 1)) {
- /* Bad option */
- usage(argv[0]);
- }
- else {
- /* Write data to file */
- strncpy(dfile, argv[opt++], MAX_FILE_LEN);
- dfile[MAX_FILE_LEN - 1] = '\0';
- }
- }
- else {
+ if (dfile[0]) {
/* File already specified */
usage(argv[0]);
}
+ if (!strcmp(argv[opt], "-")) {
+ /* File name set to '-' */
+ set_default_file(dfile, 0);
+ opt++;
+ }
+ else if (!strncmp(argv[opt], "-", 1)) {
+ /* Bad option */
+ usage(argv[0]);
+ }
+ else {
+ /* Write data to file */
+ 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);
+ }
}
else if (interval < 0) {
/* sadf reads current daily data file by default */
if (!dfile[0]) {
- set_default_file(&rectime, dfile, 0);
+ set_default_file(dfile, 0);
}
if (tm_start.use && tm_end.use && (tm_end.tm_hour < tm_start.tm_hour)) {
}
else if (!strcmp(argv[opt], "-o")) {
+ if (to_file[0]) {
+ /* Output file already specified */
+ usage(argv[0]);
+ }
/* Save stats to a file */
if ((argv[++opt]) && strncmp(argv[opt], "-", 1) &&
(strspn(argv[opt], DIGITS) != strlen(argv[opt]))) {
}
else if (!strcmp(argv[opt], "-f")) {
+ if (from_file[0]) {
+ /* Input file already specified */
+ usage(argv[0]);
+ }
/* Read stats from a file */
if ((argv[++opt]) && strncmp(argv[opt], "-", 1) &&
(strspn(argv[opt], DIGITS) != strlen(argv[opt]))) {
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);
}
else {
- set_default_file(&rectime, from_file, day_offset);
+ set_default_file(from_file, day_offset);
}
}
/* 'sar' is equivalent to 'sar -f' */
if ((argc == 1) ||
((interval < 0) && !from_file[0] && !to_file[0])) {
- set_default_file(&rectime, from_file, day_offset);
+ set_default_file(from_file, day_offset);
}
if (tm_start.use && tm_end.use && (tm_end.tm_hour < tm_start.tm_hour)) {