Print this page
OS-1840 fmdump shall emit JSON


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.

  25  */
  26 
  27 #include <alloca.h>
  28 #include <unistd.h>
  29 #include <limits.h>
  30 #include <strings.h>
  31 #include <stdlib.h>
  32 #include <stdarg.h>
  33 #include <stdio.h>
  34 #include <errno.h>
  35 #include <time.h>
  36 #include <ctype.h>
  37 #include <regex.h>
  38 #include <dirent.h>
  39 #include <pthread.h>
  40 
  41 #include <fmdump.h>
  42 
  43 #define FMDUMP_EXIT_SUCCESS     0
  44 #define FMDUMP_EXIT_FATAL       1


 176         return (buf);
 177 }
 178 
 179 /* BEGIN CSTYLED */
 180 static const char *synopsis =
 181 "Usage: %s [[-e | -i | -I] | -A ] [-f] [-mvVp] [-c class] [-R root]\n"
 182         "\t      [-t time ][-T time] [-u uuid] [-n name[.name]*[=value]] "
 183                                                         "[file]...\n    "
 184     "Log selection: [-e | -i | -I] or one [file]; default is the fault log\n"
 185         "\t-e  display error log content\n"
 186         "\t-i  display infolog content\n"
 187         "\t-I  display the high-value-infolog content\n"
 188         "\t-R  set root directory for pathname expansions\n    "
 189     "Command behaviour:\n"
 190         "\t-A  Aggregate specified [file]s or, if no [file], all known logs\n"
 191         "\t-f  follow growth of log file by waiting for additional data\n    "
 192     "Output options:\n"
 193         "\t-m  display human-readable messages (only for fault logs)\n"
 194         "\t-v  set verbose mode: display additional event detail\n"
 195         "\t-V  set very verbose mode: display complete event contents\n"
 196         "\t-p  Used with -V: apply some output prettification\n    "

 197     "Selection filters:\n"
 198         "\t-c  select events that match the specified class\n"
 199         "\t-t  select events that occurred after the specified time\n"
 200         "\t-T  select events that occurred before the specified time\n"
 201         "\t-u  select events that match the specified diagnosis uuid\n"
 202         "\t-n  select events containing named nvpair (with matching value)\n";
 203 /* END CSTYLED */
 204 
 205 static int
 206 usage(FILE *fp)
 207 {
 208         (void) fprintf(fp, synopsis, g_pname);
 209         return (FMDUMP_EXIT_USAGE);
 210 }
 211 
 212 /*ARGSUSED*/
 213 static int
 214 error(fmd_log_t *lp, void *private)
 215 {
 216         fmdump_warn("skipping record: %s\n",


1010         struct loglink *ll;
1011 
1012         (void) pthread_mutex_lock(&pl->pl_lock);
1013         pl->pl_started = 1;
1014         (void) pthread_mutex_unlock(&pl->pl_lock);
1015         (void) pthread_cond_signal(&pl->pl_cv);
1016 
1017         for (ll = pl->pl_rotated; ll != NULL; ll = ll->next)
1018                 pipeline_process(pl, ll->path, B_FALSE);
1019 
1020         pipeline_process(pl, pl->pl_logpath, pl->pl_follow);
1021         pipeline_done(pl);
1022 
1023         return (NULL);
1024 }
1025 
1026 
1027 static int
1028 aggregate(char **ifiles, int n_ifiles, int opt_f,
1029     fmd_log_filter_t *fv, uint_t fc,
1030     int opt_v, int opt_V, int opt_p)
1031 {
1032         struct fmdump_pipeline *pipeline, *pl;
1033         struct fmdump_srlzer srlzer;
1034         uint32_t npipe;
1035         int fmt;
1036         int i;
1037 
1038         if (ifiles != NULL) {
1039                 npipe = n_ifiles;
1040                 pipeline = calloc(npipe, sizeof (struct fmdump_pipeline));
1041                 if (!pipeline)
1042                         fmdump_fatal("failed to allocate memory");
1043 
1044                 for (i = 0; i < n_ifiles; i++)
1045                         pipeline[i].pl_logpath = ifiles[i];
1046         } else {
1047                 pipeline = calloc(sizeof (logtypes) / sizeof (logtypes[0]),
1048                     sizeof (struct fmdump_pipeline));
1049                 if (!pipeline)
1050                         fmdump_fatal("failed to allocate memory");


1057                         char *logpath;
1058 
1059                         if (ltp->lt_enabled == B_FALSE)
1060                                 continue;
1061 
1062                         if ((logpath = malloc(PATH_MAX)) == NULL)
1063                                 fmdump_fatal("failed to allocate memory");
1064 
1065                         (void) snprintf(logpath, PATH_MAX,
1066                             "%s/var/fm/fmd/%s",
1067                             g_root ? g_root : "", ltp->lt_logname);
1068 
1069                         pipeline[npipe].pl_rotated =
1070                             get_rotated_logs(logpath);
1071 
1072                         pipeline[npipe++].pl_logpath = logpath;
1073                 }
1074         }
1075 
1076         if (opt_V)
1077                 fmt = opt_p ? FMDUMP_PRETTY : FMDUMP_VERB2;

1078         else if (opt_v)
1079                 fmt = FMDUMP_VERB1;
1080         else
1081                 fmt = FMDUMP_SHORT;
1082 
1083         bzero(&srlzer, sizeof (srlzer));
1084         srlzer.ds_pipearr = pipeline;
1085         srlzer.ds_pipecnt = npipe;
1086         srlzer.ds_slot = calloc(npipe, sizeof (struct fmdump_srlzer_slot));
1087         if (!srlzer.ds_slot)
1088                 fmdump_fatal("failed to allocate memory");
1089         (void) pthread_mutex_init(&srlzer.ds_lock, NULL);
1090 
1091         for (i = 0, pl = &pipeline[0]; i < npipe; i++, pl++) {
1092                 (void) pthread_mutex_init(&pl->pl_lock, NULL);
1093                 (void) pthread_cond_init(&pl->pl_cv, NULL);
1094                 srlzer.ds_slot[i].ss_state = FMDUMP_PIPE_PROCESSING;
1095                 pl->pl_srlzer = &srlzer;
1096                 pl->pl_srlzeridx = i;
1097                 pl->pl_follow = opt_f ? B_TRUE : B_FALSE;


1135 {
1136         int i;
1137 
1138         if (ifiles == NULL)
1139                 return;
1140 
1141         for (i = 0; i < n_ifiles; i++) {
1142                 if (ifiles[i] != NULL) {
1143                         free(ifiles[i]);
1144                         ifiles[i] = NULL;
1145                 }
1146         }
1147 
1148         free(ifiles);
1149 }
1150 
1151 int
1152 main(int argc, char *argv[])
1153 {
1154         int opt_a = 0, opt_e = 0, opt_f = 0, opt_H = 0, opt_m = 0, opt_p = 0;
1155         int opt_u = 0, opt_v = 0, opt_V = 0;
1156         int opt_i = 0, opt_I = 0;
1157         int opt_A = 0;
1158         char **ifiles = NULL;
1159         char *ifile = NULL;
1160         int n_ifiles;
1161         int ifileidx = 0;
1162         int iflags = 0;
1163 
1164         fmdump_arg_t arg;
1165         fmdump_lyr_t lyr;
1166         const fmdump_ops_t *ops;
1167         fmd_log_filter_t *filtv;
1168         uint_t filtc;
1169 
1170         fmd_log_filter_t *errfv, *fltfv, *allfv;
1171         uint_t errfc = 0, fltfc = 0, allfc = 0;
1172 
1173         fmd_log_header_t log;
1174         fmd_log_rec_f *func;
1175         void *farg;
1176         fmd_log_t *lp;
1177         int c, err;
1178         off64_t off = 0;
1179         ulong_t recs;
1180         struct loglink *rotated_logs = NULL, *llp;
1181 
1182         g_pname = argv[0];
1183 
1184         errfv = alloca(sizeof (fmd_log_filter_t) * argc);
1185         fltfv = alloca(sizeof (fmd_log_filter_t) * argc);
1186         allfv = alloca(sizeof (fmd_log_filter_t) * argc);
1187 
1188         while (optind < argc) {
1189                 while ((c =
1190                     getopt(argc, argv, "Aac:efHiImn:O:pR:t:T:u:vV")) != EOF) {
1191                         switch (c) {
1192                         case 'A':
1193                                 opt_A++;
1194                                 break;
1195                         case 'a':
1196                                 opt_a++;
1197                                 break;
1198                         case 'c':
1199                                 errfv[errfc].filt_func = fmd_log_filter_class;
1200                                 errfv[errfc].filt_arg = optarg;
1201                                 allfv[allfc++] = errfv[errfc++];
1202                                 break;
1203                         case 'e':
1204                                 if (opt_i)
1205                                         return (usage(stderr));
1206                                 opt_e++;
1207                                 break;
1208                         case 'f':
1209                                 opt_f++;
1210                                 break;
1211                         case 'H':
1212                                 opt_H++;
1213                                 break;
1214                         case 'i':
1215                                 if (opt_e || opt_I)
1216                                         return (usage(stderr));
1217                                 opt_i++;
1218                                 break;
1219                         case 'I':
1220                                 if (opt_e || opt_i)
1221                                         return (usage(stderr));
1222                                 opt_I++;
1223                                 break;





1224                         case 'm':
1225                                 opt_m++;
1226                                 break;
1227                         case 'O':
1228                                 off = strtoull(optarg, NULL, 16);
1229                                 iflags |= FMD_LOG_XITER_OFFS;
1230                                 break;
1231                         case 'p':


1232                                 opt_p++;
1233                                 break;
1234                         case 'R':
1235                                 g_root = optarg;
1236                                 break;
1237                         case 't':
1238                                 errfv[errfc].filt_func = fmd_log_filter_after;
1239                                 errfv[errfc].filt_arg = gettimeopt(optarg);
1240                                 allfv[allfc++] = errfv[errfc++];
1241                                 break;
1242                         case 'T':
1243                                 errfv[errfc].filt_func = fmd_log_filter_before;
1244                                 errfv[errfc].filt_arg = gettimeopt(optarg);
1245                                 allfv[allfc++] = errfv[errfc++];
1246                                 break;
1247                         case 'u':
1248                                 fltfv[fltfc].filt_func = fmd_log_filter_uuid;
1249                                 fltfv[fltfc].filt_arg = optarg;
1250                                 allfv[allfc++] = fltfv[fltfc++];
1251                                 opt_u++;


1292 
1293                         if ((dest = malloc(PATH_MAX)) == NULL)
1294                                 fmdump_fatal("failed to allocate memory");
1295 
1296                         (void) strlcpy(dest, argv[optind++], PATH_MAX);
1297                         ifiles[ifileidx++] = dest;
1298                 }
1299         }
1300 
1301         if (opt_A) {
1302                 int rc;
1303 
1304                 if (!opt_a) {
1305                         fltfv[fltfc].filt_func = log_filter_silent;
1306                         fltfv[fltfc].filt_arg = (void *)1;
1307                         allfv[allfc++] = fltfv[fltfc++];
1308                 }
1309 
1310                 rc = aggregate(ifiles, n_ifiles, opt_f,
1311                     allfv, allfc,
1312                     opt_v, opt_V, opt_p);
1313 
1314                 cleanup(ifiles, n_ifiles);
1315                 return (rc);
1316         } else {
1317                 if (ifiles == NULL) {
1318                         if ((ifile = calloc(1, PATH_MAX)) == NULL)
1319                                 fmdump_fatal("failed to allocate memory");
1320                 } else {
1321                         ifile = ifiles[0];
1322                 }
1323         }
1324 
1325 
1326         if (*ifile == '\0') {
1327                 const char *pfx, *sfx;
1328 
1329                 if (opt_u || (!opt_e && !opt_i && !opt_I)) {
1330                         pfx = "flt";
1331                         sfx = "";
1332                 } else {


1383 
1384         if (opt_e && opt_u)
1385                 ops = &fmdump_err_ops;
1386         else if (strcmp(fmd_log_label(lp), fmdump_flt_ops.do_label) == 0)
1387                 ops = &fmdump_flt_ops;
1388         else if (strcmp(fmd_log_label(lp), fmdump_asru_ops.do_label) == 0)
1389                 ops = &fmdump_asru_ops;
1390         else if (strcmp(fmd_log_label(lp), fmdump_info_ops.do_label) == 0)
1391                 ops = &fmdump_info_ops;
1392         else
1393                 ops = &fmdump_err_ops;
1394 
1395         if (!opt_a && ops == &fmdump_flt_ops) {
1396                 fltfv[fltfc].filt_func = log_filter_silent;
1397                 fltfv[fltfc].filt_arg = NULL;
1398                 allfv[allfc++] = fltfv[fltfc++];
1399         }
1400 
1401         if (opt_V) {
1402                 arg.da_fmt =
1403                     &ops->do_formats[opt_p ? FMDUMP_PRETTY : FMDUMP_VERB2];

1404                 iflags |= FMD_LOG_XITER_REFS;
1405         } else if (opt_v) {
1406                 arg.da_fmt = &ops->do_formats[FMDUMP_VERB1];
1407         } else if (opt_m) {
1408                 arg.da_fmt = &ops->do_formats[FMDUMP_MSG];
1409         } else
1410                 arg.da_fmt = &ops->do_formats[FMDUMP_SHORT];
1411 
1412         if (opt_m && arg.da_fmt->do_func == NULL) {
1413                 fmdump_usage("-m mode is not supported for "
1414                     "log of type %s: %s\n", fmd_log_label(lp), ifile);
1415         }
1416 
1417         arg.da_fv = errfv;
1418         arg.da_fc = errfc;
1419         arg.da_fp = stdout;
1420 
1421         if (iflags & FMD_LOG_XITER_OFFS)
1422                 fmdump_printf(arg.da_fp, "%16s ", "OFFSET");
1423 




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  26  */
  27 
  28 #include <alloca.h>
  29 #include <unistd.h>
  30 #include <limits.h>
  31 #include <strings.h>
  32 #include <stdlib.h>
  33 #include <stdarg.h>
  34 #include <stdio.h>
  35 #include <errno.h>
  36 #include <time.h>
  37 #include <ctype.h>
  38 #include <regex.h>
  39 #include <dirent.h>
  40 #include <pthread.h>
  41 
  42 #include <fmdump.h>
  43 
  44 #define FMDUMP_EXIT_SUCCESS     0
  45 #define FMDUMP_EXIT_FATAL       1


 177         return (buf);
 178 }
 179 
 180 /* BEGIN CSTYLED */
 181 static const char *synopsis =
 182 "Usage: %s [[-e | -i | -I] | -A ] [-f] [-mvVp] [-c class] [-R root]\n"
 183         "\t      [-t time ][-T time] [-u uuid] [-n name[.name]*[=value]] "
 184                                                         "[file]...\n    "
 185     "Log selection: [-e | -i | -I] or one [file]; default is the fault log\n"
 186         "\t-e  display error log content\n"
 187         "\t-i  display infolog content\n"
 188         "\t-I  display the high-value-infolog content\n"
 189         "\t-R  set root directory for pathname expansions\n    "
 190     "Command behaviour:\n"
 191         "\t-A  Aggregate specified [file]s or, if no [file], all known logs\n"
 192         "\t-f  follow growth of log file by waiting for additional data\n    "
 193     "Output options:\n"
 194         "\t-m  display human-readable messages (only for fault logs)\n"
 195         "\t-v  set verbose mode: display additional event detail\n"
 196         "\t-V  set very verbose mode: display complete event contents\n"
 197         "\t-p  Used with -V: apply some output prettification\n"
 198         "\t-j  Used with -V: emit JSON-formatted output\n    "
 199     "Selection filters:\n"
 200         "\t-c  select events that match the specified class\n"
 201         "\t-t  select events that occurred after the specified time\n"
 202         "\t-T  select events that occurred before the specified time\n"
 203         "\t-u  select events that match the specified diagnosis uuid\n"
 204         "\t-n  select events containing named nvpair (with matching value)\n";
 205 /* END CSTYLED */
 206 
 207 static int
 208 usage(FILE *fp)
 209 {
 210         (void) fprintf(fp, synopsis, g_pname);
 211         return (FMDUMP_EXIT_USAGE);
 212 }
 213 
 214 /*ARGSUSED*/
 215 static int
 216 error(fmd_log_t *lp, void *private)
 217 {
 218         fmdump_warn("skipping record: %s\n",


1012         struct loglink *ll;
1013 
1014         (void) pthread_mutex_lock(&pl->pl_lock);
1015         pl->pl_started = 1;
1016         (void) pthread_mutex_unlock(&pl->pl_lock);
1017         (void) pthread_cond_signal(&pl->pl_cv);
1018 
1019         for (ll = pl->pl_rotated; ll != NULL; ll = ll->next)
1020                 pipeline_process(pl, ll->path, B_FALSE);
1021 
1022         pipeline_process(pl, pl->pl_logpath, pl->pl_follow);
1023         pipeline_done(pl);
1024 
1025         return (NULL);
1026 }
1027 
1028 
1029 static int
1030 aggregate(char **ifiles, int n_ifiles, int opt_f,
1031     fmd_log_filter_t *fv, uint_t fc,
1032     int opt_v, int opt_V, int opt_p, int opt_j)
1033 {
1034         struct fmdump_pipeline *pipeline, *pl;
1035         struct fmdump_srlzer srlzer;
1036         uint32_t npipe;
1037         int fmt;
1038         int i;
1039 
1040         if (ifiles != NULL) {
1041                 npipe = n_ifiles;
1042                 pipeline = calloc(npipe, sizeof (struct fmdump_pipeline));
1043                 if (!pipeline)
1044                         fmdump_fatal("failed to allocate memory");
1045 
1046                 for (i = 0; i < n_ifiles; i++)
1047                         pipeline[i].pl_logpath = ifiles[i];
1048         } else {
1049                 pipeline = calloc(sizeof (logtypes) / sizeof (logtypes[0]),
1050                     sizeof (struct fmdump_pipeline));
1051                 if (!pipeline)
1052                         fmdump_fatal("failed to allocate memory");


1059                         char *logpath;
1060 
1061                         if (ltp->lt_enabled == B_FALSE)
1062                                 continue;
1063 
1064                         if ((logpath = malloc(PATH_MAX)) == NULL)
1065                                 fmdump_fatal("failed to allocate memory");
1066 
1067                         (void) snprintf(logpath, PATH_MAX,
1068                             "%s/var/fm/fmd/%s",
1069                             g_root ? g_root : "", ltp->lt_logname);
1070 
1071                         pipeline[npipe].pl_rotated =
1072                             get_rotated_logs(logpath);
1073 
1074                         pipeline[npipe++].pl_logpath = logpath;
1075                 }
1076         }
1077 
1078         if (opt_V)
1079                 fmt = opt_p ? FMDUMP_PRETTY : opt_j ? FMDUMP_JSON :
1080                     FMDUMP_VERB2;
1081         else if (opt_v)
1082                 fmt = FMDUMP_VERB1;
1083         else
1084                 fmt = FMDUMP_SHORT;
1085 
1086         bzero(&srlzer, sizeof (srlzer));
1087         srlzer.ds_pipearr = pipeline;
1088         srlzer.ds_pipecnt = npipe;
1089         srlzer.ds_slot = calloc(npipe, sizeof (struct fmdump_srlzer_slot));
1090         if (!srlzer.ds_slot)
1091                 fmdump_fatal("failed to allocate memory");
1092         (void) pthread_mutex_init(&srlzer.ds_lock, NULL);
1093 
1094         for (i = 0, pl = &pipeline[0]; i < npipe; i++, pl++) {
1095                 (void) pthread_mutex_init(&pl->pl_lock, NULL);
1096                 (void) pthread_cond_init(&pl->pl_cv, NULL);
1097                 srlzer.ds_slot[i].ss_state = FMDUMP_PIPE_PROCESSING;
1098                 pl->pl_srlzer = &srlzer;
1099                 pl->pl_srlzeridx = i;
1100                 pl->pl_follow = opt_f ? B_TRUE : B_FALSE;


1138 {
1139         int i;
1140 
1141         if (ifiles == NULL)
1142                 return;
1143 
1144         for (i = 0; i < n_ifiles; i++) {
1145                 if (ifiles[i] != NULL) {
1146                         free(ifiles[i]);
1147                         ifiles[i] = NULL;
1148                 }
1149         }
1150 
1151         free(ifiles);
1152 }
1153 
1154 int
1155 main(int argc, char *argv[])
1156 {
1157         int opt_a = 0, opt_e = 0, opt_f = 0, opt_H = 0, opt_m = 0, opt_p = 0;
1158         int opt_u = 0, opt_v = 0, opt_V = 0, opt_j = 0;
1159         int opt_i = 0, opt_I = 0;
1160         int opt_A = 0;
1161         char **ifiles = NULL;
1162         char *ifile = NULL;
1163         int n_ifiles;
1164         int ifileidx = 0;
1165         int iflags = 0;
1166 
1167         fmdump_arg_t arg;
1168         fmdump_lyr_t lyr;
1169         const fmdump_ops_t *ops;
1170         fmd_log_filter_t *filtv;
1171         uint_t filtc;
1172 
1173         fmd_log_filter_t *errfv, *fltfv, *allfv;
1174         uint_t errfc = 0, fltfc = 0, allfc = 0;
1175 
1176         fmd_log_header_t log;
1177         fmd_log_rec_f *func;
1178         void *farg;
1179         fmd_log_t *lp;
1180         int c, err;
1181         off64_t off = 0;
1182         ulong_t recs;
1183         struct loglink *rotated_logs = NULL, *llp;
1184 
1185         g_pname = argv[0];
1186 
1187         errfv = alloca(sizeof (fmd_log_filter_t) * argc);
1188         fltfv = alloca(sizeof (fmd_log_filter_t) * argc);
1189         allfv = alloca(sizeof (fmd_log_filter_t) * argc);
1190 
1191         while (optind < argc) {
1192                 while ((c =
1193                     getopt(argc, argv, "Aac:efHiIjmn:O:pR:t:T:u:vV")) != EOF) {
1194                         switch (c) {
1195                         case 'A':
1196                                 opt_A++;
1197                                 break;
1198                         case 'a':
1199                                 opt_a++;
1200                                 break;
1201                         case 'c':
1202                                 errfv[errfc].filt_func = fmd_log_filter_class;
1203                                 errfv[errfc].filt_arg = optarg;
1204                                 allfv[allfc++] = errfv[errfc++];
1205                                 break;
1206                         case 'e':
1207                                 if (opt_i)
1208                                         return (usage(stderr));
1209                                 opt_e++;
1210                                 break;
1211                         case 'f':
1212                                 opt_f++;
1213                                 break;
1214                         case 'H':
1215                                 opt_H++;
1216                                 break;
1217                         case 'i':
1218                                 if (opt_e || opt_I)
1219                                         return (usage(stderr));
1220                                 opt_i++;
1221                                 break;
1222                         case 'I':
1223                                 if (opt_e || opt_i)
1224                                         return (usage(stderr));
1225                                 opt_I++;
1226                                 break;
1227                         case 'j':
1228                                 if (opt_p)
1229                                         return (usage(stderr));
1230                                 opt_j++;
1231                                 break;
1232                         case 'm':
1233                                 opt_m++;
1234                                 break;
1235                         case 'O':
1236                                 off = strtoull(optarg, NULL, 16);
1237                                 iflags |= FMD_LOG_XITER_OFFS;
1238                                 break;
1239                         case 'p':
1240                                 if (opt_j)
1241                                         return (usage(stderr));
1242                                 opt_p++;
1243                                 break;
1244                         case 'R':
1245                                 g_root = optarg;
1246                                 break;
1247                         case 't':
1248                                 errfv[errfc].filt_func = fmd_log_filter_after;
1249                                 errfv[errfc].filt_arg = gettimeopt(optarg);
1250                                 allfv[allfc++] = errfv[errfc++];
1251                                 break;
1252                         case 'T':
1253                                 errfv[errfc].filt_func = fmd_log_filter_before;
1254                                 errfv[errfc].filt_arg = gettimeopt(optarg);
1255                                 allfv[allfc++] = errfv[errfc++];
1256                                 break;
1257                         case 'u':
1258                                 fltfv[fltfc].filt_func = fmd_log_filter_uuid;
1259                                 fltfv[fltfc].filt_arg = optarg;
1260                                 allfv[allfc++] = fltfv[fltfc++];
1261                                 opt_u++;


1302 
1303                         if ((dest = malloc(PATH_MAX)) == NULL)
1304                                 fmdump_fatal("failed to allocate memory");
1305 
1306                         (void) strlcpy(dest, argv[optind++], PATH_MAX);
1307                         ifiles[ifileidx++] = dest;
1308                 }
1309         }
1310 
1311         if (opt_A) {
1312                 int rc;
1313 
1314                 if (!opt_a) {
1315                         fltfv[fltfc].filt_func = log_filter_silent;
1316                         fltfv[fltfc].filt_arg = (void *)1;
1317                         allfv[allfc++] = fltfv[fltfc++];
1318                 }
1319 
1320                 rc = aggregate(ifiles, n_ifiles, opt_f,
1321                     allfv, allfc,
1322                     opt_v, opt_V, opt_p, opt_j);
1323 
1324                 cleanup(ifiles, n_ifiles);
1325                 return (rc);
1326         } else {
1327                 if (ifiles == NULL) {
1328                         if ((ifile = calloc(1, PATH_MAX)) == NULL)
1329                                 fmdump_fatal("failed to allocate memory");
1330                 } else {
1331                         ifile = ifiles[0];
1332                 }
1333         }
1334 
1335 
1336         if (*ifile == '\0') {
1337                 const char *pfx, *sfx;
1338 
1339                 if (opt_u || (!opt_e && !opt_i && !opt_I)) {
1340                         pfx = "flt";
1341                         sfx = "";
1342                 } else {


1393 
1394         if (opt_e && opt_u)
1395                 ops = &fmdump_err_ops;
1396         else if (strcmp(fmd_log_label(lp), fmdump_flt_ops.do_label) == 0)
1397                 ops = &fmdump_flt_ops;
1398         else if (strcmp(fmd_log_label(lp), fmdump_asru_ops.do_label) == 0)
1399                 ops = &fmdump_asru_ops;
1400         else if (strcmp(fmd_log_label(lp), fmdump_info_ops.do_label) == 0)
1401                 ops = &fmdump_info_ops;
1402         else
1403                 ops = &fmdump_err_ops;
1404 
1405         if (!opt_a && ops == &fmdump_flt_ops) {
1406                 fltfv[fltfc].filt_func = log_filter_silent;
1407                 fltfv[fltfc].filt_arg = NULL;
1408                 allfv[allfc++] = fltfv[fltfc++];
1409         }
1410 
1411         if (opt_V) {
1412                 arg.da_fmt =
1413                     &ops->do_formats[opt_p ? FMDUMP_PRETTY :
1414                     opt_j ? FMDUMP_JSON : FMDUMP_VERB2];
1415                 iflags |= FMD_LOG_XITER_REFS;
1416         } else if (opt_v) {
1417                 arg.da_fmt = &ops->do_formats[FMDUMP_VERB1];
1418         } else if (opt_m) {
1419                 arg.da_fmt = &ops->do_formats[FMDUMP_MSG];
1420         } else
1421                 arg.da_fmt = &ops->do_formats[FMDUMP_SHORT];
1422 
1423         if (opt_m && arg.da_fmt->do_func == NULL) {
1424                 fmdump_usage("-m mode is not supported for "
1425                     "log of type %s: %s\n", fmd_log_label(lp), ifile);
1426         }
1427 
1428         arg.da_fv = errfv;
1429         arg.da_fc = errfc;
1430         arg.da_fp = stdout;
1431 
1432         if (iflags & FMD_LOG_XITER_OFFS)
1433                 fmdump_printf(arg.da_fp, "%16s ", "OFFSET");
1434