FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian dpkg

 
 
LinkBack Thread Tools
 
Old 01-30-2012, 07:41 PM
Cleber Rosa
 
Default RFC: Fix grub detection on SuSE systems: lba and boot information

This patch adds code that gets lba and boot device information on
SuSE systems, which is done by looking at the commands that were
used to install grub on that system, and match information with
grub's device.map file.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
---
grubby.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++--
1 files changed, 232 insertions(+), 6 deletions(-)

diff --git a/grubby.c b/grubby.c
index 601ba8d..c664387 100644
--- a/grubby.c
+++ b/grubby.c
@@ -56,6 +56,16 @@ int debug = 0; /* Currently just for template debugging */
#define NOOP_OPCODE 0x90
#define JMP_SHORT_OPCODE 0xeb

+/*
+ * This SuSE grub configuration file at this location is not your average
+ * grub configuration file, but instead the grub commands used to setup
+ * grub on that system.
+ */
+#define SUSE_GRUB_CONF "/etc/grub.conf"
+#define SUSE_RELEASE_FILE "/etc/SuSE-release"
+#define GRUB_DEVICE_MAP "/boot/grub/device.map"
+
+
/* comments get lumped in with indention */
struct lineElement {
char * item;
@@ -1938,6 +1948,202 @@ void displayEntry(struct singleEntry * entry, const char * prefix, int index) {
}
}

+int isSuseGrubConf(const char * path) {
+ FILE * grubConf;
+ char * line = NULL;
+ size_t len = 0;
+
+ grubConf = fopen(path, "r");
+ if (!grubConf) {
+ dbgPrintf("Could not open SuSE configuration file '%s'
",
+ SUSE_GRUB_CONF);
+ return 1;
+ }
+
+ if (getline(&line, &len, grubConf) == -1) {
+ dbgPrintf("Could not read line from file '%s'
",
+ SUSE_GRUB_CONF);
+ return 1;
+ }
+
+ if (strncmp(line, "setup", 5)) {
+ dbgPrintf("SuSE configuration file '%s' does not appear to be valid
",
+ SUSE_GRUB_CONF);
+ return 1;
+ }
+
+ free(line);
+ fclose(grubConf);
+ return 0;
+}
+
+int suseGrubConfGetLba(const char * path, int * lbaPtr) {
+ FILE * grubConf;
+ char * line = NULL;
+ size_t len = 0;
+
+ if (!path) return 1;
+ if (!lbaPtr) return 1;
+
+ grubConf = fopen(path, "r");
+ if (!grubConf) return 1;
+
+ while (getline(&line, &len, grubConf) != -1) {
+ if (!strncmp(line, "setup", 5)) {
+ if (strstr(line, "--force-lba")) {
+ *lbaPtr = 1;
+ } else {
+ *lbaPtr = 0;
+ }
+ dbgPrintf("lba: %i
", *lbaPtr);
+ break;
+ }
+ }
+
+ free(line);
+ fclose(grubConf);
+ return 0;
+}
+
+int suseGrubConfGetInstallDevice(const char * path, char ** devicePtr) {
+ FILE * grubConf;
+ char * line = NULL;
+ size_t len = 0;
+ char * lastParamPtr = NULL;
+ char * secLastParamPtr = NULL;
+ char installDeviceNumber = '';
+
+ if (!path) return 1;
+ if (!devicePtr) return 1;
+
+ grubConf = fopen(path, "r");
+ if (!grubConf) return 1;
+
+ while (getline(&line, &len, grubConf) != -1) {
+ /*
+ * If this is a line with a valid setup command, it will contain
+ * the device grub will be installed to.
+ */
+ if (!strncmp(line, "setup", 5)) {
+
+ lastParamPtr = line + strlen(line);
+
+ if (*--lastParamPtr == '
')
+ *lastParamPtr = '';
+
+ /* Last parameter in grub may be an optional IMAGE_DEVICE */
+ while (!isspace(*lastParamPtr))
+ lastParamPtr--;
+ lastParamPtr++;
+
+ secLastParamPtr = lastParamPtr - 2;
+ dbgPrintf("lastParamPtr: %s
", lastParamPtr);
+ if (!strncmp(lastParamPtr, "(hd", 3))
+ lastParamPtr += 3;
+ dbgPrintf("lastParamPtr: %c
", *lastParamPtr);
+
+ /*
+ * Second last parameter will point out if last parameter is
+ * either an IMAGE_DEVICE or INSTALL_DEVICE
+ */
+ while (!isspace(*secLastParamPtr))
+ secLastParamPtr--;
+ secLastParamPtr++;
+
+ dbgPrintf("secLastParamPtr: %s
", secLastParamPtr);
+ if (!strncmp(secLastParamPtr, "(hd", 3)) {
+ secLastParamPtr += 3;
+ dbgPrintf("secLastParamPtr: %c
", *secLastParamPtr);
+
+ installDeviceNumber = *secLastParamPtr;
+ } else {
+ installDeviceNumber = *lastParamPtr;
+ }
+
+ *devicePtr = malloc(6);
+ snprintf(*devicePtr, 6, "(hd%c)", installDeviceNumber);
+ dbgPrintf("installDeviceNumber: %c
", installDeviceNumber);
+ break;
+ }
+ }
+
+ free(line);
+ fclose(grubConf);
+ return 0;
+}
+
+int grubGetBootFromDeviceMap(const char * path,
+ const char * device,
+ char ** bootPtr) {
+ FILE * deviceMap;
+ char * line = NULL;
+ size_t len = 0;
+ char * devicePtr;
+ char * end;
+
+ if (!path) return 1;
+ if (!device) return 1;
+ if (!bootPtr) return 1;
+
+ deviceMap = fopen(path, "r");
+ if (!deviceMap) return 1;
+
+ while (getline(&line, &len, deviceMap) != -1) {
+ if (strncmp(line, "#", 1)) {
+ devicePtr = line;
+ while (isspace(*line))
+ devicePtr++;
+ dbgPrintf("device: %s
", devicePtr);
+
+ if (!strncmp(devicePtr, device, strlen(device))) {
+ devicePtr += strlen(device);
+ while (isspace(*devicePtr))
+ devicePtr++;
+
+ end = strchr(devicePtr, '
');
+ if (end)
+ *end = '';
+
+ *bootPtr = strdup(devicePtr);
+ break;
+ }
+ }
+ }
+
+ free(line);
+ fclose(deviceMap);
+ return 0;
+}
+
+int suseGrubConfGetBoot(const char * path, char ** bootPtr) {
+ char * grubDevice;
+
+ suseGrubConfGetInstallDevice(path, &grubDevice);
+ dbgPrintf("grubby installation device: %s
", grubDevice);
+
+ grubGetBootFromDeviceMap(GRUB_DEVICE_MAP, grubDevice, bootPtr);
+ dbgPrintf("boot: %s
", *bootPtr);
+
+ return 0;
+}
+
+int parseSuseGrubConf(int * lbaPtr, char ** bootPtr) {
+ if (isSuseGrubConf(SUSE_GRUB_CONF)) return 1;
+
+ if (lbaPtr) {
+ *lbaPtr = 0;
+ if (suseGrubConfGetLba(SUSE_GRUB_CONF, lbaPtr))
+ return 1;
+ }
+
+ if (bootPtr) {
+ *bootPtr = NULL;
+ suseGrubConfGetBoot(SUSE_GRUB_CONF, bootPtr);
+ }
+
+ return 0;
+}
+
int parseSysconfigGrub(int * lbaPtr, char ** bootPtr) {
FILE * in;
char buf[1024];
@@ -1988,11 +2194,19 @@ int parseSysconfigGrub(int * lbaPtr, char ** bootPtr) {
void dumpSysconfigGrub(void) {
char * boot;
int lba;
+ int notOnSuse;

- if (!parseSysconfigGrub(&lba, &boot)) {
- if (lba) printf("lba
");
- if (boot) printf("boot=%s
", boot);
+ notOnSuse = access(SUSE_RELEASE_FILE, R_OK);
+ if (notOnSuse) {
+ if (parseSysconfigGrub(&lba, &boot))
+ return;
+ } else {
+ if (parseSuseGrubConf(&lba, &boot))
+ return;
}
+
+ if (lba) printf("lba
");
+ if (boot) printf("boot=%s
", boot);
}

int displayInfo(struct grubConfig * config, char * kernel,
@@ -2812,9 +3026,14 @@ int checkForGrub(struct grubConfig * config) {
int fd;
unsigned char bootSect[512];
char * boot;
+ int notOnSuse;

- if (parseSysconfigGrub(NULL, &boot))
- return 0;
+ notOnSuse = access(SUSE_RELEASE_FILE, R_OK);
+ if (notOnSuse) {
+ if (parseSysconfigGrub(NULL, &boot)) return 0;
+ } else {
+ if (parseSuseGrubConf(NULL, &boot)) return 0;
+ }

/* assume grub is not installed -- not an error condition */
if (!boot)
@@ -2833,7 +3052,14 @@ int checkForGrub(struct grubConfig * config) {
}
close(fd);

- return checkDeviceBootloader(boot, bootSect);
+ if (notOnSuse)
+ return checkDeviceBootloader(boot, bootSect);
+ else
+ /*
+ * The more elaborate checks do not work on SuSE. The checks done
+ * seem to be reasonble (at least for now), so just return success
+ */
+ return 2;
}

int checkForExtLinux(struct grubConfig * config) {
--
1.7.6.5

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 

Thread Tools




All times are GMT. The time now is 05:10 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org