Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add scat program to cat logs on obmc #74

Merged
merged 1 commit into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions devnotes/scat/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export PATH := $(PWD)/.build/armv6-obmc-linux-gnueabi/buildtools/bin/:$(PATH)
CROSS := armv6-obmc-linux-gnueabi-

CC := $(CROSS)gcc
STRIP := $(CROSS)strip
CFLAGS := -march=armv6zk -mcpu=arm1176jz-s

scat: scat.c
$(CC) -o $@ $^ $(CFLAGS)
$(STRIP) -S $@

clean:
$(RM) scat
52 changes: 52 additions & 0 deletions devnotes/scat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
## cat for obmc-console

Server of [obmc-console] used by Talos 2 communicates with its client using
Unix socket with abstract address (see `man 7 unix`). BMC doesn't have much
tools installed and it's not clear if there are any for sockets with abstract
addresses, so here's a tiny C program to get the output (socket name is
hard-coded at the moment).

It's purpose is to collect logs without a tty, so that termination of ssh
connection wouldn't interrupt anything.

### Prebuilt binary

For convenience, binary is provided right here to avoid building toolchain.

### Building from sources

Target system uses armv6 which is not supported by popular prebuilt toolchains
macpijan marked this conversation as resolved.
Show resolved Hide resolved
for years, so `crosstool-ng` configuration for building required toolchain is
provided, skip below if you have a suitable one already.

Prerequisites:
* [crosstool-ng]
* regular build environment with GCC, GNU make and binutils

Preparation:
```bash
# build toolchain for armv6
ct-ng armv6-obmc-linux-gnueabi
ct-ng build
```

Build `scat` binary:
```bash
make
```

With your own toolchain, proceed as usual:
```bash
CROSS=armv6-linux-gnueabi- make
```

### Usage

```
$ scp scat root@talos:/tmp
$ ssh root@talos
# /tmp/scat | gzip > /tmp/boot-log &
```

[crosstool-ng]: https://crosstool-ng.github.io/
[obmc-console]: https://github.com/openbmc/obmc-console
Binary file added devnotes/scat/prebuilt-scat
Binary file not shown.
10 changes: 10 additions & 0 deletions devnotes/scat/samples/armv6-obmc-linux-gnueabi/crosstool.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CT_CONFIG_VERSION="3"
# CT_REMOVE_DOCS is not set
CT_ARCH_ARM=y
CT_ARCH_ARCH="armv6"
CT_ARCH_FLOAT_SW=y
CT_KERNEL_LINUX=y
CT_LINUX_V_4_18=y
# CT_CC_GCC_USE_GRAPHITE is not set
# CT_CC_GCC_USE_LTO is not set
# CT_CC_GCC_SJLJ_EXCEPTIONS is not set
3 changes: 3 additions & 0 deletions devnotes/scat/samples/armv6-obmc-linux-gnueabi/reported.by
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
reporter_name=""
reporter_url=""
reporter_comment=""
72 changes: 72 additions & 0 deletions devnotes/scat/scat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <signal.h>

#define BUFFER_SIZE 128

#define SOCKET_NAME "\0obmc-console"
#define SOCKET_NAME_LEN (sizeof(SOCKET_NAME) - 1)

void signal_noop(int s)
{
}

int main(int argc, char *argv[])
{
struct sockaddr_un addr;
int ret;
int sock;
char buffer[BUFFER_SIZE];
struct sigaction action;

// Make Ctrl+C cause read() to return EINTR
action.sa_handler = &signal_noop;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGINT, &action, NULL);

sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket");
exit(EXIT_FAILURE);
}

memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
memcpy(addr.sun_path, SOCKET_NAME, SOCKET_NAME_LEN);

ret = connect(sock,
(const struct sockaddr *)&addr,
sizeof(addr) - sizeof(addr.sun_path) + SOCKET_NAME_LEN);
if (ret == -1) {
fprintf(stderr, "Can't connect: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}

while (1) {
ret = read(sock, buffer, sizeof(buffer) - 1);
if (ret == 0)
break;
if (ret == -1) {
if (errno == EINTR) {
// Do an async read() to get last portion of data or we won't
// miss anything anyway?
break;
}

perror("read");
exit(EXIT_FAILURE);
}

buffer[ret - 1] = '\0';
fputs(buffer, stdout);
}

close(sock);
return EXIT_SUCCESS;
}