Add --debug style logging (for both success and failures) to /var/log/grubby
Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
parent
24e2f46051
commit
a10345813c
414
0001-Add-logging-when-things-fail.patch
Normal file
414
0001-Add-logging-when-things-fail.patch
Normal file
@ -0,0 +1,414 @@
|
||||
From bfb7c70e7eaa1311cadc716c303ca694163f9e2f Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Tue, 19 Feb 2013 18:00:36 -0500
|
||||
Subject: [PATCH] Add logging when things fail.
|
||||
|
||||
Actually also logs when things succeed.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
grubby.c | 92 ++++++++++++++++++++++++++++----------
|
||||
log.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
log.h | 27 ++++++++++++
|
||||
test/results/debug/g2.1 | 1 +
|
||||
5 files changed, 212 insertions(+), 24 deletions(-)
|
||||
create mode 100644 log.c
|
||||
create mode 100644 log.h
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index fcf2dd2..325ffd8 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -20,7 +20,7 @@
|
||||
VERSION=8.22
|
||||
|
||||
TARGETS = grubby
|
||||
-OBJECTS = grubby.o
|
||||
+OBJECTS = grubby.o log.o
|
||||
|
||||
CC = gcc
|
||||
RPM_OPT_FLAGS := -O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector
|
||||
diff --git a/grubby.c b/grubby.c
|
||||
index edbeb64..408e3ca 100644
|
||||
--- a/grubby.c
|
||||
+++ b/grubby.c
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <signal.h>
|
||||
#include <blkid/blkid.h>
|
||||
|
||||
+#include "log.h"
|
||||
+
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
@@ -58,6 +60,8 @@ int debug = 0; /* Currently just for template debugging */
|
||||
|
||||
int isEfi = 0;
|
||||
|
||||
+char *saved_command_line = NULL;
|
||||
+
|
||||
/* comments get lumped in with indention */
|
||||
struct lineElement {
|
||||
char * item;
|
||||
@@ -1533,43 +1537,67 @@ static char *findDiskForRoot()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-void printEntry(struct singleEntry * entry) {
|
||||
+void printEntry(struct singleEntry * entry, FILE *f) {
|
||||
int i;
|
||||
struct singleLine * line;
|
||||
|
||||
for (line = entry->lines; line; line = line->next) {
|
||||
- fprintf(stderr, "DBG: %s", line->indent);
|
||||
+ log_message(f, "DBG: %s", line->indent);
|
||||
for (i = 0; i < line->numElements; i++) {
|
||||
/* Need to handle this, because we strip the quotes from
|
||||
* menuentry when read it. */
|
||||
if (line->type == LT_MENUENTRY && i == 1) {
|
||||
if(!isquote(*line->elements[i].item))
|
||||
- fprintf(stderr, "\'%s\'", line->elements[i].item);
|
||||
+ log_message(f, "\'%s\'", line->elements[i].item);
|
||||
else
|
||||
- fprintf(stderr, "%s", line->elements[i].item);
|
||||
- fprintf(stderr, "%s", line->elements[i].indent);
|
||||
+ log_message(f, "%s", line->elements[i].item);
|
||||
+ log_message(f, "%s", line->elements[i].indent);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
- fprintf(stderr, "%s%s",
|
||||
+ log_message(f, "%s%s",
|
||||
line->elements[i].item, line->elements[i].indent);
|
||||
}
|
||||
- fprintf(stderr, "\n");
|
||||
+ log_message(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
-void notSuitablePrintf(struct singleEntry * entry, const char *fmt, ...)
|
||||
+void notSuitablePrintf(struct singleEntry * entry, int okay, const char *fmt, ...)
|
||||
{
|
||||
- va_list argp;
|
||||
+ static int once;
|
||||
+ va_list argp, argq;
|
||||
|
||||
- if (!debug)
|
||||
+ va_start(argp, fmt);
|
||||
+
|
||||
+ va_copy(argq, argp);
|
||||
+ if (!once) {
|
||||
+ log_time(NULL);
|
||||
+ log_message(NULL, "command line: %s\n", saved_command_line);
|
||||
+ }
|
||||
+ log_message(NULL, "DBG: Image entry %s: ", okay ? "succeeded" : "failed");
|
||||
+ log_vmessage(NULL, fmt, argq);
|
||||
+
|
||||
+ printEntry(entry, NULL);
|
||||
+ va_end(argq);
|
||||
+
|
||||
+ if (!debug) {
|
||||
+ once = 1;
|
||||
+ va_end(argp);
|
||||
return;
|
||||
+ }
|
||||
|
||||
- va_start(argp, fmt);
|
||||
+ if (okay) {
|
||||
+ va_end(argp);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!once)
|
||||
+ log_message(stderr, "DBG: command line: %s\n", saved_command_line);
|
||||
+ once = 1;
|
||||
fprintf(stderr, "DBG: Image entry failed: ");
|
||||
vfprintf(stderr, fmt, argp);
|
||||
- printEntry(entry);
|
||||
+ printEntry(entry, stderr);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
@@ -1596,22 +1624,25 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix,
|
||||
char * rootdev;
|
||||
|
||||
if (skipRemoved && entry->skip) {
|
||||
- notSuitablePrintf(entry, "marked to skip\n");
|
||||
+ notSuitablePrintf(entry, 0, "marked to skip\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);
|
||||
if (!line) {
|
||||
- notSuitablePrintf(entry, "no line found\n");
|
||||
+ notSuitablePrintf(entry, 0, "no line found\n");
|
||||
return 0;
|
||||
}
|
||||
if (line->numElements < 2) {
|
||||
- notSuitablePrintf(entry, "line has only %d elements\n",
|
||||
+ notSuitablePrintf(entry, 0, "line has only %d elements\n",
|
||||
line->numElements);
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (flags & GRUBBY_BADIMAGE_OKAY) return 1;
|
||||
+ if (flags & GRUBBY_BADIMAGE_OKAY) {
|
||||
+ notSuitablePrintf(entry, 1, "\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
fullName = alloca(strlen(bootPrefix) +
|
||||
strlen(line->elements[1].item) + 1);
|
||||
@@ -1622,7 +1653,7 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix,
|
||||
sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/",
|
||||
line->elements[1].item + rootspec_offset);
|
||||
if (access(fullName, R_OK)) {
|
||||
- notSuitablePrintf(entry, "access to %s failed\n", fullName);
|
||||
+ notSuitablePrintf(entry, 0, "access to %s failed\n", fullName);
|
||||
return 0;
|
||||
}
|
||||
for (i = 2; i < line->numElements; i++)
|
||||
@@ -1643,7 +1674,7 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix,
|
||||
|
||||
/* failed to find one */
|
||||
if (!line) {
|
||||
- notSuitablePrintf(entry, "no line found\n");
|
||||
+ notSuitablePrintf(entry, 0, "no line found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1652,7 +1683,7 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix,
|
||||
if (i < line->numElements)
|
||||
dev = line->elements[i].item + 5;
|
||||
else {
|
||||
- notSuitablePrintf(entry, "no root= entry found\n");
|
||||
+ notSuitablePrintf(entry, 0, "no root= entry found\n");
|
||||
/* it failed too... can't find root= */
|
||||
return 0;
|
||||
}
|
||||
@@ -1661,32 +1692,33 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix,
|
||||
|
||||
dev = getpathbyspec(dev);
|
||||
if (!getpathbyspec(dev)) {
|
||||
- notSuitablePrintf(entry, "can't find blkid entry for %s\n", dev);
|
||||
+ notSuitablePrintf(entry, 0, "can't find blkid entry for %s\n", dev);
|
||||
return 0;
|
||||
} else
|
||||
dev = getpathbyspec(dev);
|
||||
|
||||
rootdev = findDiskForRoot();
|
||||
if (!rootdev) {
|
||||
- notSuitablePrintf(entry, "can't find root device\n");
|
||||
+ notSuitablePrintf(entry, 0, "can't find root device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!getuuidbydev(rootdev) || !getuuidbydev(dev)) {
|
||||
- notSuitablePrintf(entry, "uuid missing: rootdev %s, dev %s\n",
|
||||
+ notSuitablePrintf(entry, 0, "uuid missing: rootdev %s, dev %s\n",
|
||||
getuuidbydev(rootdev), getuuidbydev(dev));
|
||||
free(rootdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(getuuidbydev(rootdev), getuuidbydev(dev))) {
|
||||
- notSuitablePrintf(entry, "uuid mismatch: rootdev %s, dev %s\n",
|
||||
+ notSuitablePrintf(entry, 0, "uuid mismatch: rootdev %s, dev %s\n",
|
||||
getuuidbydev(rootdev), getuuidbydev(dev));
|
||||
free(rootdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(rootdev);
|
||||
+ notSuitablePrintf(entry, 1, "\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -3898,6 +3930,20 @@ int main(int argc, const char ** argv) {
|
||||
|
||||
signal(SIGSEGV, traceback);
|
||||
|
||||
+ int i = 0;
|
||||
+ for (int j = 1; j < argc; j++)
|
||||
+ i += strlen(argv[j]) + 1;
|
||||
+ saved_command_line = malloc(i);
|
||||
+ if (!saved_command_line) {
|
||||
+ fprintf(stderr, "grubby: %m\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ saved_command_line[0] = '\0';
|
||||
+ for (int j = 1; j < argc; j++) {
|
||||
+ strcat(saved_command_line, argv[j]);
|
||||
+ strncat(saved_command_line, j == argc -1 ? "" : " ", 1);
|
||||
+ }
|
||||
+
|
||||
optCon = poptGetContext("grubby", argc, argv, options, 0);
|
||||
poptReadDefaultConfig(optCon, 1);
|
||||
|
||||
diff --git a/log.c b/log.c
|
||||
new file mode 100644
|
||||
index 0000000..1ddb8c1
|
||||
--- /dev/null
|
||||
+++ b/log.c
|
||||
@@ -0,0 +1,114 @@
|
||||
+/*
|
||||
+ * log.c
|
||||
+ *
|
||||
+ * Copyright 2013 Red Hat, Inc.
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _GNU_SOURCE
|
||||
+#define _GNU_SOURCE
|
||||
+#endif
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <time.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+
|
||||
+static int log_fd = -1;
|
||||
+static FILE *f = NULL;
|
||||
+
|
||||
+static int
|
||||
+open_log(void)
|
||||
+{
|
||||
+ if (log_fd > -1)
|
||||
+ return 0;
|
||||
+ log_fd = open("/var/log/grubby", O_RDWR|O_APPEND|O_CREAT|O_CLOEXEC, 0600);
|
||||
+ if (log_fd < 0)
|
||||
+ return log_fd;
|
||||
+
|
||||
+ f = fdopen(log_fd, "a+");
|
||||
+ if (f == NULL) {
|
||||
+ typeof(errno) saved_errno = errno;
|
||||
+ close(log_fd);
|
||||
+ log_fd = -1;
|
||||
+ errno = saved_errno;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ setbuf(f, NULL);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+log_time(FILE *log)
|
||||
+{
|
||||
+ if (!log) {
|
||||
+ int rc = open_log();
|
||||
+ if (rc < 0)
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ time_t t = time(NULL);
|
||||
+ char timestr[27];
|
||||
+
|
||||
+ ctime_r(&t, timestr);
|
||||
+ timestr[26] = '\0';
|
||||
+ for (int i = 26; i >= 0; i--)
|
||||
+ if (timestr[i] == '\n')
|
||||
+ timestr[i] = '\0';
|
||||
+
|
||||
+ return log_message(log, "DBG: %d: %s: ", getpid(), timestr);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+log_vmessage(FILE *log, const char *msg, va_list ap)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ if (!msg)
|
||||
+ return -1;
|
||||
+ if (msg[0] == '\0')
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!log) {
|
||||
+ rc = open_log();
|
||||
+ if (rc < 0)
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ vfprintf(log ? log : f, msg, ap);
|
||||
+ fdatasync(log ? fileno(log) : log_fd);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+log_message(FILE *log, const char *msg, ...)
|
||||
+{
|
||||
+ va_list argp;
|
||||
+
|
||||
+ va_start(argp, msg);
|
||||
+ int rc = log_vmessage(log, msg, argp);
|
||||
+ va_end(argp);
|
||||
+ return rc;
|
||||
+}
|
||||
diff --git a/log.h b/log.h
|
||||
new file mode 100644
|
||||
index 0000000..082a59e
|
||||
--- /dev/null
|
||||
+++ b/log.h
|
||||
@@ -0,0 +1,27 @@
|
||||
+/*
|
||||
+ * log.h
|
||||
+ *
|
||||
+ * Copyright 2013 Red Hat, Inc.
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+#ifndef GRUBBY_LOG_H
|
||||
+#define GRUBBY_LOG_H 1
|
||||
+
|
||||
+extern int log_time(FILE *log);
|
||||
+extern int log_vmessage(FILE *log, const char *msg, va_list ap);
|
||||
+extern int log_message(FILE *log, const char *msg, ...);
|
||||
+
|
||||
+#endif /* GRUBBY_LOG_H */
|
||||
diff --git a/test/results/debug/g2.1 b/test/results/debug/g2.1
|
||||
index 9de4595..45c64ae 100644
|
||||
--- a/test/results/debug/g2.1
|
||||
+++ b/test/results/debug/g2.1
|
||||
@@ -1,3 +1,4 @@
|
||||
+DBG: command line: --grub2 -c test/grub2.1 --boot-filesystem=/boot --default-kernel --debug
|
||||
DBG: Image entry failed: access to /boot/vmlinuz-2.6.38.8-32.fc15.x86_64 failed
|
||||
DBG: menuentry 'Linux, with Fedora 2.6.38.8-32.fc15.x86_64' --class gnu-linux --class gnu --class os {
|
||||
DBG: load_video
|
||||
--
|
||||
1.8.1.2
|
||||
|
@ -1,6 +1,6 @@
|
||||
Name: grubby
|
||||
Version: 8.22
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: Command line tool for updating bootloader configs
|
||||
Group: System Environment/Base
|
||||
License: GPLv2+
|
||||
@ -21,6 +21,8 @@ Requires: s390utils-base
|
||||
Requires: uboot-tools
|
||||
%endif
|
||||
|
||||
Patch0: 0001-Add-logging-when-things-fail.patch
|
||||
|
||||
%description
|
||||
grubby is a command line tool for updating and displaying information about
|
||||
the configuration files for the grub, lilo, elilo (ia64), yaboot (powerpc)
|
||||
@ -71,6 +73,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Feb 20 2013 Peter Jones <pjones@redhat.com> - 8.22-3
|
||||
- Add --debug style logging (for both success and failures) to /var/log/grubby
|
||||
|
||||
* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 8.22-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user