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
|
Name: grubby
|
||||||
Version: 8.22
|
Version: 8.22
|
||||||
Release: 2%{?dist}
|
Release: 3%{?dist}
|
||||||
Summary: Command line tool for updating bootloader configs
|
Summary: Command line tool for updating bootloader configs
|
||||||
Group: System Environment/Base
|
Group: System Environment/Base
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
@ -21,6 +21,8 @@ Requires: s390utils-base
|
|||||||
Requires: uboot-tools
|
Requires: uboot-tools
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
Patch0: 0001-Add-logging-when-things-fail.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
grubby is a command line tool for updating and displaying information about
|
grubby is a command line tool for updating and displaying information about
|
||||||
the configuration files for the grub, lilo, elilo (ia64), yaboot (powerpc)
|
the configuration files for the grub, lilo, elilo (ia64), yaboot (powerpc)
|
||||||
@ -71,6 +73,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%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
|
* 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
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user