From ee71c69502d694eb247196ab0725e48be7cf57de Mon Sep 17 00:00:00 2001 From: Mikhail Efremov Date: Thu, 7 Dec 2017 17:20:20 +0300 Subject: [PATCH] Use ramdisk_size from kernel cmdline If we can't get file's size then use ramdisk_size if given. --- config-stage1.h | 6 ------ disk.c | 6 +++--- network.c | 12 ++++++++---- stage1.c | 2 +- tools.c | 41 +++++++++++++++++++++++++++++++++++++---- tools.h | 1 + 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/config-stage1.h b/config-stage1.h index 94afe53..5258785 100644 --- a/config-stage1.h +++ b/config-stage1.h @@ -18,12 +18,6 @@ #define _GNU_SOURCE 1 #include "version.h" -/* If we have more than that amount of memory (in bytes), we assume we can load the second stage as a ramdisk */ -#define MEM_LIMIT_RAMDISK (256 * 1024 * 1024) - -/* If we have more than that amount of memory (in bytes), we assume we can load the rescue as a ramdisk */ -#define MEM_LIMIT_RESCUE (128 * 1024 * 1024) - #define VERSION_FILE "/.VERSION" #define RAMDISK_LOCATION "/" #define IMAGE_LOCATION "/image" diff --git a/disk.c b/disk.c index 9669eda..eb5545b 100644 --- a/disk.c +++ b/disk.c @@ -310,11 +310,11 @@ static enum return_type try_with_partition(char *choice) goto err; } - if (stat(ramdisk_path, &statbuf)) { - stg1_error_message("Could not get ramdisk size: %s", strerror(errno)); + ramdisk_size = get_ramdisk_size(ramdisk_path); + if (ramdisk_size == 0) { + stg1_error_message("Could not get %s size: %s", ramdisk_path, strerror(errno)); goto err; } - ramdisk_size = (unsigned long)statbuf.st_size; log_message("found the %s Installation, good news!", version); diff --git a/network.c b/network.c index 3d76773..5f2d883 100644 --- a/network.c +++ b/network.c @@ -763,11 +763,13 @@ enum return_type ftp_prepare(void) char * questions_auto[] = { "server", "directory", "user", "pass", NULL }; static char ** answers = NULL; enum return_type results; + unsigned long ramdisk_size; update_splash("prepare"); - if (!ramdisk_possible(MEM_LIMIT_RAMDISK)) { + ramdisk_size = get_ramdisk_size(NULL); + if (!ramdisk_possible(ramdisk_size)) { stg1_error_message("FTP install needs more than %d Mbytes of memory (detected %u Mbytes).", - BYTES2MB(MEM_LIMIT_RAMDISK), BYTES2MB(total_memory())); + BYTES2MB(ramdisk_size), BYTES2MB(total_memory())); return RETURN_ERROR; } @@ -854,12 +856,14 @@ enum return_type http_prepare(void) char * questions_auto[] = { "server", "directory", NULL }; static char ** answers = NULL; enum return_type results; + unsigned long ramdisk_size; update_splash("prepare"); - if (!ramdisk_possible(MEM_LIMIT_RAMDISK)) { + ramdisk_size = get_ramdisk_size(NULL); + if (!ramdisk_possible(ramdisk_size)) { stg1_error_message("HTTP install needs more than %d Mbytes of memory (detected %u Mbytes).", - BYTES2MB(MEM_LIMIT_RAMDISK), BYTES2MB(total_memory())); + BYTES2MB(ramdisk_size), BYTES2MB(total_memory())); return RETURN_ERROR; } diff --git a/stage1.c b/stage1.c index 0d9cd19..f23ef8f 100644 --- a/stage1.c +++ b/stage1.c @@ -342,7 +342,7 @@ void stage1() init_frontend(buf); update_splash("init_frontend"); - if (IS_RESCUE && !ramdisk_possible(MEM_LIMIT_RESCUE)) { + if (IS_RESCUE && !ramdisk_possible(get_ramdisk_size(NULL))) { stg1_error_message("You are starting the rescue with a low memory configuration. " "From that point, experience showed us that the program may stop " "or crash at any point without immediate proper reason. Continue at " diff --git a/tools.c b/tools.c index 2039354..a83fc13 100644 --- a/tools.c +++ b/tools.c @@ -48,8 +48,15 @@ #include "init.h" #endif +/* If we have more than that amount of memory (in bytes), we assume we can load the second stage as a ramdisk */ +#define MEM_LIMIT_RAMDISK (256 * 1024 * 1024) + +/* If we have more than that amount of memory (in bytes), we assume we can load the rescue as a ramdisk */ +#define MEM_LIMIT_RESCUE (128 * 1024 * 1024) + static struct param_elem params[50]; static int param_number = 0; +static unsigned long cmdline_ramdisk_size = 0; void process_cmdline(void) { @@ -105,6 +112,17 @@ void process_cmdline(void) set_param(MODE_AUTOMATIC); grab_automatic_params(value); } + if (!strcmp(name, "ramdisk_size")) { + long tmp; + char *endptr = NULL; + errno = 0; + tmp = strtol(value, &endptr, 0); + if (errno == 0 && endptr && *endptr == '\0' && tmp > 0) { + /* ramdisk_size in cmdline given in Kbs, convert + * its value to bytes */ + cmdline_ramdisk_size = (unsigned long)tmp * 1024; + } + } if (buf[i] == '\0') break; i++; @@ -213,6 +231,23 @@ unsigned long total_memory(void) return value; } +unsigned long get_ramdisk_size(const char *ramdisk_path) +{ + /* If path is given then use it and return 0 if stat failed */ + if (ramdisk_path) { + struct stat statbuf; + + return stat(ramdisk_path, &statbuf) ? 0 : (unsigned long)statbuf.st_size; + } + + /* Use ramdisk_size from cmdline if given */ + if (cmdline_ramdisk_size) + return cmdline_ramdisk_size; + + /* Fallback to hardcoded values as last resort */ + return IS_RESCUE ? MEM_LIMIT_RESCUE : MEM_LIMIT_RAMDISK; +} + int ramdisk_possible(unsigned long ramdisk_size) { @@ -229,7 +264,6 @@ int ramdisk_possible(unsigned long ramdisk_size) } } - static void save_stuff_for_rescue(void) { char * file = "/etc/resolv.conf"; @@ -453,10 +487,9 @@ enum return_type load_ramdisk(char *ramdisk_path, unsigned long size) } if (size == 0) { - struct stat statr; - if (stat(img_name, &statr)) + size = get_ramdisk_size(img_name); + if (size == 0) return RETURN_ERROR; - size = (unsigned long)statr.st_size; } return load_ramdisk_fd(st2_fd, size); diff --git a/tools.h b/tools.h index b71a777..39658a1 100644 --- a/tools.h +++ b/tools.h @@ -31,6 +31,7 @@ void unset_param(int i); int charstar_to_int(char * s); /* Returns total memory in Kb */ unsigned long total_memory(void); +unsigned long get_ramdisk_size(const char *ramdisk_path); int ramdisk_possible(unsigned long ramdisk_size); char * get_ramdisk_realname(void); enum return_type load_ramdisk(char *, unsigned long size);