Skip to content
Snippets Groups Projects
Commit b789751a authored by Alessandro Rubini's avatar Alessandro Rubini
Browse files

zio-dump: support several ctrl/data pairs on cmdline


Signed-off-by: default avatarAlessandro Rubini <rubini@gnudd.com>
Acked-by: default avatarFederico Vaga <federico.vaga@gmail.com>
parent dd40dc76
No related merge requests found
...@@ -10,40 +10,138 @@ ...@@ -10,40 +10,138 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/select.h>
#include <linux/zio.h> #include <linux/zio.h>
#include <linux/zio-buffer.h> #include <linux/zio-buffer.h>
#define FD_C 0
#define FD_D 1
#define ZIO_CONTROL_SIZE 512
#define ZIO_NAME_LEN 32
unsigned char buf[1024*1024]; unsigned char buf[1024*1024];
char *prgname;
void read_channel(int cfd, int dfd, FILE *log)
{
struct zio_control ctrl;
int i, j;
i = read(cfd, &ctrl, sizeof(ctrl));
switch(i) {
case -1:
fprintf(stderr, "%s: control read: %s\n",
prgname, strerror(errno));
exit(1);
case 0:
fprintf(stderr, "%s: control read: unexpected EOF\n",
prgname);
exit(1);
default:
fprintf(stderr, "%s: ctrl read: %i bytes (expected %i)\n",
prgname, i, sizeof(ctrl));
/* continue anyways */
case sizeof(ctrl):
break; /* ok */
}
printf("Ctrl: version %i.%i, trigger %.16s, dev %.16s, "
"cset %i, chan %i\n",
ctrl.major_version, ctrl.minor_version,
ctrl.triggername, ctrl.devname, ctrl.cset_i,
ctrl.chan_i);
printf("Ctrl: seq %i, n %i, size %i, bits %i, "
"flags %08x (%s)\n",
ctrl.seq_num,
ctrl.nsamples,
ctrl.ssize,
ctrl.sbits,
ctrl.flags,
ctrl.flags & ZIO_CONTROL_LITTLE_ENDIAN
? "little-endian" :
ctrl.flags & ZIO_CONTROL_BIG_ENDIAN
? "big-endian" : "unknown-endian");
printf("Ctrl: stamp %lli.%09lli (%lli)\n",
(long long)ctrl.tstamp.secs,
(long long)ctrl.tstamp.ticks,
(long long)ctrl.tstamp.bins);
/* FIXME: some control information is missing */
i = read(dfd, buf, sizeof(buf));
if (i < 0) {
fprintf(stderr, "%s: data read: %s\n",
prgname, strerror(errno));
return; /* next ctrl, let's see... */
}
if (!i) {
fprintf(stderr, "%s: data read: unexpected EOF\n", prgname);
return;
}
if (i != ctrl.nsamples * ctrl.ssize) {
if (i == sizeof(buf)) {
fprintf(stderr, "%s: buffer too small: "
"please fix me and recompile\n", prgname);
/* FIXME: empty the data channel */
} else {
fprintf(stderr, "%s: ctrl: read %i bytes "
"(exp %i)\n", prgname, i,
ctrl.nsamples * ctrl.ssize);
}
/* continue anyways */
}
fwrite(buf, 1, i, log);
/* report data to stdout */
for (j = 0; j < i; j++) {
if (!(j & 0xf))
printf("Data:");
printf(" %02x", buf[j]);
if ((j & 0xf) == 0xf || j == i - 1)
putchar('\n');
}
putchar('\n');
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *f; FILE *f;
char *outfname; char *outfname;
int fd[2]; int *cfd; /* control file descriptors */
int i, j; int *dfd; /* data file descriptors */
fd_set control_set, ready_set;
int i, j, maxfd, ndev;
if (argc != 3) { if (argc < 3 || (argc & 1) != 1) {
fprintf(stderr, "%s: use \"%s <ctrl-file> <data-file>\"\n", fprintf(stderr, "%s: Wrong number of arguments\n"
"Use: \"%s <ctrl-file> <data-file> [...]\"\n",
argv[0], argv[0]); argv[0], argv[0]);
exit(1); exit(1);
} }
prgname = argv[0];
cfd = malloc(argc / 2 * sizeof(*cfd));
dfd = malloc(argc / 2 * sizeof(*dfd));
if (!cfd || !dfd) {
fprintf(stderr, "%s: malloc: %s\n", prgname, strerror(errno));
exit(1);
}
for (i = 0; i < 2; i++) { /* Open all pairs, and build the fd_set for later select() */
fd[i] = open(argv[i + 1], O_RDONLY); FD_ZERO(&control_set);
if (fd[i] < 0) { for (i = 1, j = 0; i < argc; i+=2, j++) {
fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i + 1], cfd[j] = open(argv[i], O_RDONLY);
dfd[j] = open(argv[i + 1], O_RDONLY);
if (cfd[j] < 0) {
fprintf(stderr, "%s: %s: %s\n", prgname, argv[i],
strerror(errno));
exit(1);
}
if (dfd[j] < 0) {
fprintf(stderr, "%s: %s: %s\n", prgname, argv[i + 1],
strerror(errno)); strerror(errno));
exit(1); exit(1);
} }
/* ctrl file is used in select, data file is non-blocking */
FD_SET(cfd[j], &control_set);
fcntl(dfd[j], F_SETFL, fcntl(dfd[j], F_GETFL) | O_NONBLOCK);
maxfd = dfd[j];
} }
/* the data channel is non-blocking */ ndev = j;
fcntl(fd[FD_D], F_SETFL, fcntl(fd[FD_D], F_GETFL) | O_NONBLOCK);
/* always log data we read to some filename */ /* always log data we read to some filename */
outfname = getenv("ZIO_DUMP_TO"); outfname = getenv("ZIO_DUMP_TO");
...@@ -51,7 +149,7 @@ int main(int argc, char **argv) ...@@ -51,7 +149,7 @@ int main(int argc, char **argv)
outfname = "/dev/null"; outfname = "/dev/null";
f = fopen(outfname, "w"); f = fopen(outfname, "w");
if (!f) { if (!f) {
fprintf(stderr, "%s: %s: %s\n", argv[0], outfname, fprintf(stderr, "%s: %s: %s\n", prgname, outfname,
strerror(errno)); strerror(errno));
exit(1); exit(1);
} }
...@@ -59,83 +157,19 @@ int main(int argc, char **argv) ...@@ -59,83 +157,19 @@ int main(int argc, char **argv)
setlinebuf(stdout); setlinebuf(stdout);
setbuf(f, NULL); setbuf(f, NULL);
/* now read control and data, forever */ /* now read control and then data, forever */
while (1) { while (1) {
struct zio_control ctrl; ready_set = control_set;
i = select(maxfd + 1, &ready_set, NULL, NULL, NULL);
/* This is a blocking read to the control file */ if (i <0 && errno == EINTR)
i = read(fd[FD_C], &ctrl, sizeof(ctrl));
switch (i) {
case -1:
fprintf(stderr, "%s: %s: read(): %s\n",
argv[0], argv[1 + FD_C], strerror(errno));
exit(1);
case 0:
fprintf(stderr, "%s: %s: unexpected EOF\n",
argv[0], argv[1 + FD_C]);
exit(1);
default:
fprintf(stderr, "%s: ctrl: read %i bytes (exp %i)\n",
argv[0], i, sizeof(ctrl));
/* continue anyways */
case sizeof(ctrl):
break; /* ok */
}
printf("Ctrl: version %i.%i, trigger %.16s, dev %.16s, "
"cset %i, chan %i\n",
ctrl.major_version, ctrl.minor_version,
ctrl.triggername, ctrl.devname, ctrl.cset_i,
ctrl.chan_i);
printf("Ctrl: seq %i, n %i, size %i, bits %i, "
"flags %08x (%s)\n",
ctrl.seq_num,
ctrl.nsamples,
ctrl.ssize,
ctrl.sbits,
ctrl.flags,
ctrl.flags & ZIO_CONTROL_LITTLE_ENDIAN
? "little-endian" :
ctrl.flags & ZIO_CONTROL_BIG_ENDIAN
? "big-endian" : "unknown-endian");
printf("Ctrl: stamp %lli.%09lli (%lli)\n",
(long long)ctrl.tstamp.secs,
(long long)ctrl.tstamp.ticks,
(long long)ctrl.tstamp.bins);
/* FIXME: some control information is missing */
i = read(fd[FD_D], buf, sizeof(buf));
if (i < 0) {
fprintf(stderr, "%s: %s: read(): %s\n",
argv[0], argv[1 + FD_D], strerror(errno));
continue; /* next ctrl, let's see... */
}
if (!i) {
fprintf(stderr, "%s: %s: unexpected EOF\n",
argv[0], argv[1 + FD_D]);
continue; continue;
if (i < 0) {
fprintf(stderr, "%s: select(): %s\n", prgname,
strerror(errno));
exit(1);
} }
if (i != ctrl.nsamples * ctrl.ssize) { for (j = 0; j < ndev; j++)
if (i == sizeof(buf)) { if (FD_ISSET(cfd[j], & ready_set))
fprintf(stderr, "%s: buffer too small\n", read_channel(cfd[j], dfd[j], f);
argv[0]);
/* FIXME: empty the data channel */
} else {
fprintf(stderr, "%s: ctrl: read %i bytes "
"(exp %i)\n", argv[0], i,
ctrl.nsamples * ctrl.ssize);
}
/* continue anyways */
}
fwrite(buf, 1, i, f);
/* report data to stdout */
for (j = 0; j < i; j++) {
if (!(j & 0xf))
printf("Data:");
printf(" %02x", buf[j]);
if ((j & 0xf) == 0xf || j == i - 1)
putchar('\n');
}
putchar('\n');
} }
} }
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment