summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/disk.c15
-rw-r--r--mdk-stage1/lomount.c60
-rw-r--r--mdk-stage1/lomount.h4
-rw-r--r--mdk-stage1/mount.c9
-rw-r--r--mdk-stage1/mount.h5
5 files changed, 56 insertions, 37 deletions
diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c
index 9dff3d184..2dcaad2b8 100644
--- a/mdk-stage1/disk.c
+++ b/mdk-stage1/disk.c
@@ -206,13 +206,14 @@ static enum return_type try_with_device(char *dev_name)
char location_full[500];
char * disk_own_mount = "/tmp/hdimage";
+ char * loopdev = NULL;
char * parts[50];
char * parts_comments[50];
struct stat statbuf;
enum return_type results;
char * choice;
-
+
if (list_partitions(dev_name, parts, parts_comments)) {
stg1_error_message("Could not read partitions information.");
return RETURN_ERROR;
@@ -255,7 +256,7 @@ static enum return_type try_with_device(char *dev_name)
if (!stat(location_full, &statbuf) && !S_ISDIR(statbuf.st_mode)) {
log_message("%s exists and is not a directory, assuming this is an ISO image", location_full);
- if (lomount(location_full, IMAGE_LOCATION, 0)) {
+ if (lomount(location_full, IMAGE_LOCATION, &loopdev, 0)) {
stg1_error_message("Could not mount file %s as an ISO image of the " DISTRIB_NAME " Distribution.", answers_location[0]);
umount(disk_own_mount);
return try_with_device(dev_name);
@@ -270,13 +271,13 @@ static enum return_type try_with_device(char *dev_name)
"(I need the subdirectory " RAMDISK_LOCATION ")\n"
"Here's a short extract of the files in the directory:\n"
"%s", disk_extract_list_directory(IMAGE_LOCATION));
- loumount();
+ del_loop(loopdev);
umount(disk_own_mount);
return try_with_device(dev_name);
}
if (load_ramdisk() != RETURN_OK) {
stg1_error_message("Could not load program into memory.");
- loumount();
+ del_loop(loopdev);
umount(disk_own_mount);
return try_with_device(dev_name);
}
@@ -288,7 +289,7 @@ static enum return_type try_with_device(char *dev_name)
"(I need the subdirectory " LIVE_LOCATION ")\n"
"Here's a short extract of the files in the directory:\n"
"%s", disk_extract_list_directory(IMAGE_LOCATION));
- loumount();
+ del_loop(loopdev);
umount(disk_own_mount);
return try_with_device(dev_name);
}
@@ -296,7 +297,7 @@ static enum return_type try_with_device(char *dev_name)
stg1_error_message("The " DISTRIB_NAME " Distribution seems to be copied on a Windows partition. "
"You need more memory to perform an installation from a Windows partition. "
"Another solution if to copy the " DISTRIB_NAME " Distribution on a Linux partition.");
- loumount();
+ del_loop(loopdev);
umount(disk_own_mount);
return try_with_device(dev_name);
}
@@ -304,7 +305,7 @@ static enum return_type try_with_device(char *dev_name)
}
if (IS_RESCUE) {
- loumount();
+ del_loop(loopdev);
umount(disk_own_mount);
}
diff --git a/mdk-stage1/lomount.c b/mdk-stage1/lomount.c
index 434151d35..d940ec36f 100644
--- a/mdk-stage1/lomount.c
+++ b/mdk-stage1/lomount.c
@@ -115,13 +115,41 @@ set_loop (const char *device, const char *file, int gz)
}
-char * loopdev = "/dev/loop3"; /* Ugly. But do I care? */
+char* find_free_loop(void)
+{
+ char loopdev[] = "/dev/loop0";
+ struct loop_info loopinfo;
+ int i;
+ for (i=0; i<8; i++) {
+ int fd;
+ loopdev[9] = '0' + i;
+ ensure_dev_exists(loopdev);
+ fd = open(loopdev, O_RDONLY);
+ if (!ioctl(fd, LOOP_GET_STATUS, &loopinfo)) {
+ close(fd);
+ continue;
+ }
+ if (errno == ENXIO) {
+ log_message("%s is available", loopdev);
+ close(fd);
+ return strdup(loopdev);
+ } else {
+ log_perror("LOOP_GET_STATUS(unexpected error)");
+ close(fd);
+ continue;
+ }
+ }
+ return NULL;
+}
void
-del_loop(void)
+del_loop(char * loopdev)
{
int fd;
+ if (!loopdev)
+ return;
+
if ((fd = open (loopdev, O_RDONLY)) < 0)
return;
@@ -131,45 +159,37 @@ del_loop(void)
close (fd);
}
-
-static char * where_mounted = NULL;
-
int
-lomount(char *loopfile, char *where, int gz)
+lomount(char *loopfile, char *where, char **dev, int gz)
{
long int flag;
+ char * loopdev;
flag = MS_MGC_VAL;
flag |= MS_RDONLY;
my_insmod("loop", ANY_DRIVER_TYPE, NULL);
+ if (!(loopdev = find_free_loop())) {
+ log_message("could not find a free loop");
+ return 1;
+ }
+ if (dev)
+ *dev = loopdev;
+
if (set_loop(loopdev, loopfile, gz)) {
log_message("set_loop failed on %s (%s)", loopdev, strerror(errno));
return 1;
}
if (my_mount(loopdev, where, "iso9660", 0)) {
- del_loop();
+ del_loop(loopdev);
return 1;
}
- where_mounted = strdup(where);
log_message("lomount succeeded for %s on %s", loopfile, where);
return 0;
}
-int
-loumount()
-{
- if (where_mounted) {
- umount(where_mounted);
- where_mounted = NULL;
- }
- del_loop();
- return 0;
-}
-
-
diff --git a/mdk-stage1/lomount.h b/mdk-stage1/lomount.h
index 2d109dc05..633c5a82c 100644
--- a/mdk-stage1/lomount.h
+++ b/mdk-stage1/lomount.h
@@ -15,7 +15,7 @@
#ifndef LOMOUNT_H
#define LOMOUNT_H
-int lomount(char *loopfile, char *where, int gz);
-int loumount(void);
+int lomount(char *loopfile, char *where, char **loopdev, int gz);
+void del_loop(char *loopdev);
#endif
diff --git a/mdk-stage1/mount.c b/mdk-stage1/mount.c
index 1503a95e6..0b207c368 100644
--- a/mdk-stage1/mount.c
+++ b/mdk-stage1/mount.c
@@ -32,13 +32,12 @@
-#ifndef DISABLE_MEDIAS
/* WARNING: this won't work if the argument is not /dev/ based */
-int ensure_dev_exists(char *dev)
+int ensure_dev_exists(const char * dev)
{
int major, minor;
int type = S_IFBLK; /* my default type is block. don't forget to change for chars */
- char * name;
+ const char * name;
struct stat buf;
char * ptr;
@@ -127,6 +126,9 @@ int ensure_dev_exists(char *dev)
minor = 8 * charstar_to_int(ptr+1);
ptr = strchr(ptr, 'p');
minor += charstar_to_int(ptr+1);
+ } else if (ptr_begins_static_str(name, "loop")) {
+ major = 7;
+ minor = name[4] - '0';
} else {
log_message("I don't know how to create device %s, please post bugreport to me!", dev);
return -1;
@@ -139,7 +141,6 @@ int ensure_dev_exists(char *dev)
return 0;
}
-#endif /* DISABLE_MEDIAS */
/* mounts, creating the device if needed+possible */
diff --git a/mdk-stage1/mount.h b/mdk-stage1/mount.h
index 82795462f..3c24f8bbd 100644
--- a/mdk-stage1/mount.h
+++ b/mdk-stage1/mount.h
@@ -27,9 +27,6 @@
#endif
int my_mount(char *dev, char *location, char *fs, int force_rw);
-
-#ifndef DISABLE_MEDIAS
-int ensure_dev_exists(char *dev);
-#endif
+int ensure_dev_exists(const char * dev);
#endif