From 559e1418f2c89f5cfd50c9cb6c21865abfa22ae3 Mon Sep 17 00:00:00 2001 From: Guillaume Cottenceau Date: Wed, 22 Oct 2003 19:15:42 +0000 Subject: allow more than one loop device for more than one lomount --- mdk-stage1/disk.c | 15 +++++++------ mdk-stage1/lomount.c | 60 ++++++++++++++++++++++++++++++++++------------------ mdk-stage1/lomount.h | 4 ++-- mdk-stage1/mount.c | 9 ++++---- mdk-stage1/mount.h | 5 +---- 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 -- cgit v1.2.1