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 > Gentoo > Gentoo User

 
 
LinkBack Thread Tools
 
Old 10-13-2010, 03:11 PM
Chris Lumens
 
Default Rework how image loading works for HD installs.

This is the same as has been previously done for NFS and URL install methods.
While I'm at it, add a parseDeviceAndDir convenience function similar to what
we've got in nfsinstall.c.
---
loader/dirbrowser.c | 7 +-
loader/dirbrowser.h | 6 +-
loader/hdinstall.c | 258 +++++++++++++++++++++++----------------------------
loader/hdinstall.h | 4 +-
loader/loader.c | 2 +-
5 files changed, 128 insertions(+), 149 deletions(-)

diff --git a/loader/dirbrowser.c b/loader/dirbrowser.c
index 3783ea3..ba0a6e8 100644
--- a/loader/dirbrowser.c
+++ b/loader/dirbrowser.c
@@ -30,6 +30,8 @@
#include <string.h>
#include <sys/stat.h>

+#include "dirbrowser.h"
+
#ifndef STANDALONE
#include "../pyanaconda/isys/log.h"

@@ -51,8 +53,7 @@ static int simpleStringCmp(const void * a, const void * b) {

#define FSTEP 10

-static char ** get_file_list(char * dirname,
- int (*filterfunc)(char *, struct dirent *)) {
+char ** get_file_list(char * dirname, filterfunc_t filterfunc) {
DIR * dir;
struct dirent *entry;
char ** files;
@@ -100,7 +101,7 @@ static char ** get_file_list(char * dirname,
* the dirent for the file.
*/
char * newt_select_file(char * title, char * text, char * dirname,
- int (*filterfunc)(char *, struct dirent *)) {
+ filterfunc_t filterfunc) {
char ** files;
char * fn = NULL;
int i, done = 0;
diff --git a/loader/dirbrowser.h b/loader/dirbrowser.h
index 7fb22f2..77f5681 100644
--- a/loader/dirbrowser.h
+++ b/loader/dirbrowser.h
@@ -22,7 +22,11 @@

#include <dirent.h>

+typedef int (*filterfunc_t)(char *, struct dirent *);
+
+char **get_file_list(char *dirname, filterfunc_t filterfunc);
+
char * newt_select_file(char * title, char * text, char * dirname,
- int (*filterfunc)(char *, struct dirent *));
+ filterfunc_t filterfunc);

#endif
diff --git a/loader/hdinstall.c b/loader/hdinstall.c
index e8c9873..453a594 100644
--- a/loader/hdinstall.c
+++ b/loader/hdinstall.c
@@ -25,6 +25,7 @@

#include <ctype.h>
#include <errno.h>
+#include <dirent.h>
#include <fcntl.h>
#include <newt.h>
#include <stdlib.h>
@@ -33,6 +34,7 @@
#include <unistd.h>
#include <glib.h>

+#include "dirbrowser.h"
#include "driverdisk.h"
#include "hdinstall.h"
#include "getparts.h"
@@ -54,76 +56,85 @@
/* boot flags */
extern uint64_t flags;

-/* given a partition device and directory, tries to mount hd install image */
-static char * setupIsoImages(char * device, char * dirName, char * location) {
- int rc = 0;
- char *url = NULL, *dirspec, *updpath, *path;
+/* format is hd:device:/path */
+static void parseDeviceAndDir(char *url, char **device, char **dir) {
+ char *token, *src = NULL;

- logMessage(INFO, "mounting device %s for hard drive install", device);
+ if (!url)
+ return;

- if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL))
- return NULL;
+ /* Skip over the leading hd: if present. */
+ if (!strncmp(url, "hd:", 3))
+ url += 3;

- checked_asprintf(&dirspec, "/mnt/isodir/%.*s",
- (int) (strrchr(dirName, '/') - dirName), dirName);
- checked_asprintf(&path, "/mnt/isodir/%s", dirName);
+ logMessage(DEBUGLVL, "parseDeviceAndDir url: |%s|", url);

- if (path) {
- logMessage(INFO, "Path to stage2 image is %s", path);
+ src = strdup(url);
+ token = strtok(src, ":");
+ if (!token)
+ return;

- rc = copyFile(path, "/tmp/install.img");
- rc = mountStage2("/tmp/install.img");
+ *device = strdup(token);

- free(path);
+ token = strtok(NULL, ":");
+ if (!token)
+ *dir = strdup("/");
+ else
+ *dir = strdup(token);

- if (rc) {
- umount("/mnt/runtime");
- umount("/mnt/isodir");
- goto err;
- }
+ logMessage(DEBUGLVL, "parseDeviceAndDir device: |%s|", *device);
+ logMessage(DEBUGLVL, "parseDeviceAndDir dir: |%s|", *dir);
+}

- checked_asprintf(&updpath, "%s/updates.img", dirspec);
+static int ends_with_iso(char *dirname, struct dirent *ent) {
+ char *suffix;

- logMessage(INFO, "Looking for updates for HD in %s", updpath);
- copyUpdatesImg(updpath);
- free(updpath);
+ if (ent->d_type != DT_REG)
+ return 0;

- checked_asprintf(&updpath, "%s/product.img", dirspec);
+ suffix = rindex(ent->d_name, '.');
+ return (!strcmp(suffix, "iso"));
+}

- logMessage(INFO, "Looking for product for HD in %s", updpath);
- copyProductImg(updpath);
+int loadHdImages(struct loaderData_s *loaderData) {
+ char *device = NULL, *dir = NULL, *path;

- free(updpath);
- free(dirspec);
- umount("/mnt/isodir");
+ if (!loaderData->instRepo)
+ return 0;

- checked_asprintf(&url, "hd:%s:/%s", device,
- dirName ? dirName : ".");
+ parseDeviceAndDir(loaderData->instRepo, &device, &dir);

- return url;
+ if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL))
+ return 0;
+
+ if (dir[0] == '/') {
+ checked_asprintf(&path, "/mnt/isodir%s/updates.img", dir);
} else {
- free(dirspec);
- free(path);
+ checked_asprintf(&path, "/mnt/isodir/%s/updates.img", dir);
+ }

- if (rc) {
- umount("/mnt/isodir");
- return NULL;
- }
+ logMessage(INFO, "Looking for updates for HD in %s", path);
+ copyUpdatesImg(path);
+ free(path);
+
+ if (dir[0] == '/') {
+ checked_asprintf(&path, "/mnt/isodir%s/product.img", dir);
+ } else {
+ checked_asprintf(&path, "/mnt/isodir/%s/product.img", dir);
}

-err:
- newtWinMessage(_("Error"), _("OK"),
- _("An error occured finding the installation image "
- "on your hard drive. Please check your images and "
- "try again."));
- return NULL;
+ logMessage(INFO, "Looking for product for HD in %s", path);
+ copyProductImg(path);
+
+ free(device);
+ free(dir);
+ free(path);
+ umount("/mnt/isodir");
+
+ return 1;
}

-/* setup hard drive based install from a partition with a filesystem and
- * ISO images on that filesystem
- */
-char * mountHardDrive(struct installMethod * method,
- char * location, struct loaderData_s * loaderData) {
+int promptForHardDrive(struct loaderData_s *loaderData) {
int rc;
int i;

@@ -131,75 +142,18 @@ char * mountHardDrive(struct installMethod * method,
struct newtExitStruct es;
newtGrid entryGrid, grid, buttons;

- int done = 0;
char * dir = g_strdup("");
char * tmpDir;
- char * url = NULL;
char * buf;
int numPartitions;

+ char **files;
char **partition_list;
char *selpart;
char *kspartition = NULL, *ksdirectory = NULL;
- char *imgpath = "/images/install.img";
-
- /* handle kickstart/stage2= data first if available */
- if (loaderData->method == METHOD_HD && loaderData->stage2Data) {
- kspartition = ((struct hdInstallData *)loaderData->stage2Data)->partition;
- if (kspartition) {
- kspartition = g_strdup(kspartition);
- }
-
- ksdirectory = ((struct hdInstallData *)loaderData->stage2Data)->directory;
- if (ksdirectory) {
- if (g_str_has_suffix(ksdirectory, ".img")) {
- ksdirectory = g_strdup(ksdirectory);
- } else {
- ksdirectory = g_strconcat(ksdirectory, imgpath, NULL);
- }
- } else {
- ksdirectory = g_strdup(imgpath);
- }
-
- logMessage(INFO, "partition is %s, dir is %s", kspartition, ksdirectory);
-
- if (!kspartition || !ksdirectory) {
- logMessage(ERROR, "missing partition or directory specification");
- loaderData->method = -1;
-
- if (loaderData->inferredStage2)
- loaderData->invalidRepoParam = 1;
- } else {
- /* if we start with /dev, strip it (#121486) */
- char *kspart = kspartition;
- if (!strncmp(kspart, "/dev/", 5))
- kspart = kspart + 5;
-
- url = setupIsoImages(kspart, ksdirectory, location);
- if (!url) {
- logMessage(ERROR, "unable to find %s installation images on hd",
- getProductName());
- loaderData->method = -1;
-
- if (loaderData->inferredStage2)
- loaderData->invalidRepoParam = 1;
- } else {
- g_free(kspartition);
- g_free(ksdirectory);
- return url;
- }
- }
- } else {
- kspartition = NULL;
- ksdirectory = NULL;
- }
-
- /* if we're here its either because this is interactive, or the */
- /* hd kickstart directive was faulty and we have to prompt for */
- /* location of harddrive image */

partition_list = NULL;
- while (!done) {
+ while (1) {
/* if we're doing another pass free this up first */
if (partition_list)
freePartitionsList(partition_list);
@@ -214,8 +168,8 @@ char * mountHardDrive(struct installMethod * method,
"your system! Would you like to configure "
"additional devices?"));
if (rc == 2) {
- loaderData->stage2Data = NULL;
- return NULL;
+ loaderData->instRepo = NULL;
+ return LOADER_BACK;
}

rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL);
@@ -300,8 +254,8 @@ char * mountHardDrive(struct installMethod * method,
newtPopWindow();

if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) {
- loaderData->stage2Data = NULL;
- return NULL;
+ loaderData->instRepo = NULL;
+ return LOADER_BACK;
} else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) {
rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL);
continue;
@@ -309,37 +263,69 @@ char * mountHardDrive(struct installMethod * method,

logMessage(INFO, "partition %s selected", selpart);

- /* If the user-provided URL points at a repo instead of a stage2
- * image, fix that up now.
- */
- if (!g_str_has_suffix(dir, ".img")) {
- char *tmp = g_strconcat(dir, imgpath, NULL);
- g_free(dir);
- dir = tmp;
+ /* Now verify the ISO images pointed to contain an installation source. */
+ if (doPwMount(selpart, "/mnt/isodir", "auto", "ro", NULL)) {
+ logMessage(ERROR, "couldn't mount %s to verify images", selpart);
+ continue;
+ }
+
+ if (dir[0] == '/') {
+ checked_asprintf(&buf, "/mnt/isodir%s", dir);
+ } else {
+ checked_asprintf(&buf, "/mnt/isodir/%s", dir);
+ }
+
+ files = get_file_list(buf, ends_with_iso);
+ if (!files) {
+ newtWinMessage(_("Error"), _("OK"),
+ _("That directory does not contain installation media."));
+ umount("/mnt/isodir");
+ free(buf);
+ continue;
+ }
+
+ free(buf);
+
+ /* mount the first image and check for a .treeinfo file */
+ if (dir[0] == '/') {
+ checked_asprintf(&buf, "/mnt/isodir%s/%s", dir, files[0]);
+ } else {
+ checked_asprintf(&buf, "/mnt/isodir/%s/%s", dir, files[0]);
}

- loaderData->invalidRepoParam = 1;
+ if (doPwMount(buf, "/tmp/testmnt", "auto", "ro", NULL)) {
+ free(buf);
+ newtWinMessage(_("Error"), _("OK"),
+ _("That directory does not contain installation media."));
+ umount("/mnt/isodir");
+ continue;
+ }

- url = setupIsoImages(selpart, dir, location);
- if (!url) {
- newtWinMessage(_("Error"), _("OK"),
- _("Device %s does not appear to contain "
- "an installation image."), selpart, getProductName());
+ free(buf);
+
+ if (access("/tmp/testmnt/.treeinfo", R_OK)) {
+ newtWinMessage(_("Error"), _("OK"),
+ _("That directory does not contain installation media."));
+ umount("/tmp/testmnt");
+ umount("/mnt/isodir");
continue;
}

- done = 1;
+ umount("/tmp/testmnt");
+ umount("/mnt/isodir");
+ break;
}

+ checked_asprintf(&loaderData->instRepo, "hd:%s:/%s", selpart, dir);
g_free(dir);
+ loaderData->method = METHOD_HD;

- return url;
+ return LOADER_OK;
}

void setKickstartHD(struct loaderData_s * loaderData, int argc,
char ** argv) {
char *p;
- char *substr = NULL;
gchar *biospart = NULL, *partition = NULL, *dir = NULL;
GOptionContext *optCon = g_option_context_new(NULL);
GError *optErr = NULL;
@@ -386,19 +372,7 @@ void setKickstartHD(struct loaderData_s * loaderData, int argc,
}

loaderData->method = METHOD_HD;
- loaderData->stage2Data = calloc(sizeof(struct hdInstallData), 1);
- if (partition)
- ((struct hdInstallData *)loaderData->stage2Data)->partition = partition;
- if (dir)
- ((struct hdInstallData *)loaderData->stage2Data)->directory = dir;
-
- if (partition && dir) {
- /* set repo only if location of stage 2 is not specified explicitly in --dir */
- substr = strstr(dir, ".img");
- if (!substr || (substr && *(substr+4) != '')) {
- checked_asprintf(&(loaderData->instRepo), "hd:%s:%s", partition, dir);
- }
- }
+ checked_asprintf(&loaderData->instRepo, "hd:%s:%s", partition, dir);

logMessage(INFO, "results of hd ks, partition is %s, dir is %s", partition,
dir);
diff --git a/loader/hdinstall.h b/loader/hdinstall.h
index 44351a3..cee3e16 100644
--- a/loader/hdinstall.h
+++ b/loader/hdinstall.h
@@ -30,8 +30,8 @@ struct hdInstallData {

void setKickstartHD(struct loaderData_s * loaderData, int argc,
char ** argv);
-char * mountHardDrive(struct installMethod * method,
- char * location, struct loaderData_s * loaderData);
+int promptForHardDrive(struct loaderData_s *loaderData);
+int loadHdImages(struct loaderData_s *loaderData);
int kickstartFromHD(char *kssrc);
int kickstartFromBD(char *kssrc);

diff --git a/loader/loader.c b/loader/loader.c
index 942b5b5..044e84a 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -130,7 +130,7 @@ static const char *LANG_DEFAULT = "en_US.UTF-8";

static struct installMethod installMethods[] = {
{ N_("Local CD/DVD"), 0, DEVICE_CDROM, NULL, NULL },
- { N_("Hard drive"), 0, DEVICE_DISK, NULL, NULL },
+ { N_("Hard drive"), 0, DEVICE_DISK, promptForHardDrive, loadHdImages },
{ N_("NFS directory"), 1, DEVICE_NETWORK, promptForNfs, loadNfsImages },
{ "URL", 1, DEVICE_NETWORK, promptForUrl, loadUrlImages},
};
--
1.7.1.1

_______________________________________________
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 08:01 AM.

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