Check that RAM size is enough for ramdisk
Don't try to load ramdisk we don't have enough memory.
This commit is contained in:
parent
a9374f376e
commit
7f50a883ac
2
cdrom.c
2
cdrom.c
@ -101,7 +101,7 @@ static enum return_type do_with_device(char * dev_name, char * dev_model)
|
||||
log_message("found %s ISO9660 media, good news!", version);
|
||||
|
||||
if (IS_RESCUE) {
|
||||
load_ramdisk(NULL);
|
||||
load_ramdisk(NULL, 0);
|
||||
umount(IMAGE_LOCATION);
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,11 @@
|
||||
#define _GNU_SOURCE 1
|
||||
#include "version.h"
|
||||
|
||||
/* If we have more than that amount of memory (in Mbytes), we assume we can load the second stage as a ramdisk */
|
||||
#define MEM_LIMIT_RAMDISK 124
|
||||
/* 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 Mbytes), we assume we can load the rescue as a ramdisk */
|
||||
#define MEM_LIMIT_RESCUE 56
|
||||
/* 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 "/"
|
||||
|
49
disk.c
49
disk.c
@ -254,6 +254,8 @@ static enum return_type try_with_partition(char *choice)
|
||||
|
||||
struct stat statbuf;
|
||||
int iso = 0;
|
||||
char *ramdisk_path = NULL;
|
||||
unsigned long ramdisk_size;
|
||||
|
||||
strcpy(device_fullname, "/dev/");
|
||||
strcat(device_fullname, choice);
|
||||
@ -271,8 +273,7 @@ static enum return_type try_with_partition(char *choice)
|
||||
|
||||
snprintf(buf, sizeof(buf), "Please enter the directory (or ISO image file) containing %s distribution.", version);
|
||||
if (ask_from_entries_auto(buf, questions_location, &answers_location, 24, questions_location_auto, NULL) != RETURN_OK) {
|
||||
umount(IMAGE_LOCATION);
|
||||
return RETURN_ERROR;
|
||||
goto err;
|
||||
}
|
||||
|
||||
strcpy(location_full, IMAGE_LOCATION);
|
||||
@ -283,49 +284,63 @@ static enum return_type try_with_partition(char *choice)
|
||||
stg1_error_message("Directory or ISO image file could not be found on partition.\n"
|
||||
"Here's a short extract of the files in the root of the partition:\n"
|
||||
"%s", disk_extract_list_directory(IMAGE_LOCATION));
|
||||
umount(IMAGE_LOCATION);
|
||||
return RETURN_ERROR;
|
||||
goto err;
|
||||
}
|
||||
|
||||
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)) {
|
||||
stg1_error_message("Could not mount file %s as an ISO image of the %s Distribution.", answers_location[0], version);
|
||||
umount(IMAGE_LOCATION);
|
||||
return RETURN_ERROR;
|
||||
goto err;
|
||||
}
|
||||
iso = 1;
|
||||
add_to_env("PIGGYBACK", "1");
|
||||
}
|
||||
|
||||
if (access(get_ramdisk_path(iso ? NULL : location_full), R_OK)) {
|
||||
ramdisk_path = get_ramdisk_path(iso ? NULL : location_full);
|
||||
if (ramdisk_path == NULL) {
|
||||
stg1_error_message("Could not get ramdisk path");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (access(ramdisk_path, R_OK)) {
|
||||
stg1_error_message("I can't find the %s Distribution in the specified directory. "
|
||||
"Here's a short extract of the files in the directory:\n"
|
||||
"%s", version, disk_extract_list_directory(IMAGE_LOCATION));
|
||||
loumount();
|
||||
umount(IMAGE_LOCATION);
|
||||
return RETURN_ERROR;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (stat(ramdisk_path, &statbuf)) {
|
||||
stg1_error_message("Could not get ramdisk size: %s", strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
ramdisk_size = (unsigned long)statbuf.st_size;
|
||||
|
||||
log_message("found the %s Installation, good news!", version);
|
||||
|
||||
if (!IS_LOWMEM && ramdisk_possible()) {
|
||||
if (load_ramdisk(iso ? NULL : location_full) != RETURN_OK) {
|
||||
if (!IS_LOWMEM && ramdisk_possible(ramdisk_size)) {
|
||||
if (load_ramdisk(ramdisk_path, ramdisk_size) != RETURN_OK) {
|
||||
stg1_error_message("Could not load program into memory.");
|
||||
loumount();
|
||||
umount(IMAGE_LOCATION);
|
||||
return RETURN_ERROR;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
do_losetup(LIVE_DEVICE, get_ramdisk_path(iso ? NULL : location_full));
|
||||
do_losetup(LIVE_DEVICE, ramdisk_path);
|
||||
my_mount(LIVE_DEVICE, STAGE2_LOCATION, (IS_LIVE) ? LIVEFS : STAGE2FS, 0);
|
||||
}
|
||||
|
||||
|
||||
free(ramdisk_path);
|
||||
|
||||
add_to_env("DEVICE", choice);
|
||||
add_to_env("METHOD", strdup("disk"));
|
||||
add_to_env("PREFIX", answers_location[0]);
|
||||
|
||||
return RETURN_OK;
|
||||
|
||||
err:
|
||||
free(ramdisk_path);
|
||||
loumount();
|
||||
umount(IMAGE_LOCATION);
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
|
||||
enum return_type disk_prepare(void)
|
||||
|
12
network.c
12
network.c
@ -765,9 +765,9 @@ enum return_type ftp_prepare(void)
|
||||
enum return_type results;
|
||||
|
||||
update_splash("prepare");
|
||||
if (!ramdisk_possible()) {
|
||||
stg1_error_message("FTP install needs more than %d Mbytes of memory.",
|
||||
MEM_LIMIT_RAMDISK);
|
||||
if (!ramdisk_possible(MEM_LIMIT_RAMDISK)) {
|
||||
stg1_error_message("FTP install needs more than %d Mbytes of memory (detected %u Mbytes).",
|
||||
BYTES2MB(MEM_LIMIT_RAMDISK), BYTES2MB(total_memory()));
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
|
||||
@ -857,9 +857,9 @@ enum return_type http_prepare(void)
|
||||
|
||||
update_splash("prepare");
|
||||
|
||||
if (!ramdisk_possible()) {
|
||||
stg1_error_message("HTTP install needs more than %d Mbytes of memory.",
|
||||
MEM_LIMIT_RAMDISK);
|
||||
if (!ramdisk_possible(MEM_LIMIT_RAMDISK)) {
|
||||
stg1_error_message("HTTP install needs more than %d Mbytes of memory (detected %u Mbytes).",
|
||||
BYTES2MB(MEM_LIMIT_RAMDISK), BYTES2MB(total_memory()));
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
|
||||
|
6
stage1.c
6
stage1.c
@ -342,6 +342,12 @@ void stage1()
|
||||
init_frontend(buf);
|
||||
update_splash("init_frontend");
|
||||
|
||||
if (IS_RESCUE && !ramdisk_possible(MEM_LIMIT_RESCUE)) {
|
||||
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 "
|
||||
"your own risk. Alternatively, you may reboot your system now.");
|
||||
}
|
||||
|
||||
init = get_param_valued("init");
|
||||
if (init)
|
||||
|
56
tools.c
56
tools.c
@ -32,6 +32,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#include "stage1.h"
|
||||
#include "log.h"
|
||||
@ -196,11 +197,36 @@ int charstar_to_int(char * s)
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ramdisk_possible(void)
|
||||
/* Returns total memory in bytes */
|
||||
unsigned long total_memory(void)
|
||||
{
|
||||
struct sysinfo info;
|
||||
unsigned long value;
|
||||
|
||||
if (sysinfo(&info)) {
|
||||
log_message( "sysinfo: Can't get total memory: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = info.totalram * info.mem_unit;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
int ramdisk_possible(unsigned long ramdisk_size)
|
||||
{
|
||||
unsigned long tm = total_memory();
|
||||
|
||||
log_message("Total Memory: %u Mbytes", BYTES2MB(tm));
|
||||
|
||||
/* Assume we need at least twice of ramdisk size */
|
||||
if (total_memory() >= ramdisk_size * 2)
|
||||
return 1;
|
||||
else {
|
||||
log_message("warning, ramdisk (%u Mb) is not possible due to low mem!", BYTES2MB(ramdisk_size));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -234,7 +260,7 @@ static void save_stuff_for_rescue(void)
|
||||
}
|
||||
|
||||
|
||||
enum return_type load_ramdisk_fd(int source_fd, int size)
|
||||
enum return_type load_ramdisk_fd(int source_fd, unsigned long size)
|
||||
{
|
||||
char * ramdisk = "/dev/ram3"; /* warning, verify that this file exists in the initrd, and that root=/dev/ram3 is actually passed to the kernel at boot time */
|
||||
int ram_fd;
|
||||
@ -251,7 +277,7 @@ enum return_type load_ramdisk_fd(int source_fd, int size)
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
|
||||
init_progression(wait_msg, size);
|
||||
init_progression(wait_msg, (int)size);
|
||||
|
||||
while ((actually = read(source_fd, buffer, sizeof(buffer))) > 0) {
|
||||
seems_ok = 1;
|
||||
@ -409,14 +435,12 @@ enum return_type verify_ramdisk_digest(const char *filename, const char *sha256_
|
||||
return strcmp(computed_hash, sha256_hash) ? RETURN_ERROR : RETURN_OK;
|
||||
}
|
||||
|
||||
enum return_type load_ramdisk(char *mount_path)
|
||||
enum return_type load_ramdisk(char *ramdisk_path, unsigned long size)
|
||||
{
|
||||
int st2_fd;
|
||||
struct stat statr;
|
||||
char img_name[500];
|
||||
char *img_name;
|
||||
|
||||
strcpy(img_name, mount_path ? mount_path : IMAGE_LOCATION);
|
||||
strcat(img_name, get_ramdisk_realname());
|
||||
img_name = ramdisk_path ?: get_ramdisk_path(NULL);
|
||||
|
||||
log_message("trying to load %s as a ramdisk", img_name);
|
||||
|
||||
@ -428,10 +452,14 @@ enum return_type load_ramdisk(char *mount_path)
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
|
||||
if (stat(img_name, &statr))
|
||||
return RETURN_ERROR;
|
||||
else
|
||||
return load_ramdisk_fd(st2_fd, statr.st_size);
|
||||
if (size == 0) {
|
||||
struct stat statr;
|
||||
if (stat(img_name, &statr))
|
||||
return RETURN_ERROR;
|
||||
size = (unsigned long)statr.st_size;
|
||||
}
|
||||
|
||||
return load_ramdisk_fd(st2_fd, size);
|
||||
}
|
||||
|
||||
/* pixel's */
|
||||
|
10
tools.h
10
tools.h
@ -29,11 +29,12 @@ int get_param(int i);
|
||||
void set_param(int i);
|
||||
void unset_param(int i);
|
||||
int charstar_to_int(char * s);
|
||||
int total_memory(void);
|
||||
int ramdisk_possible(void);
|
||||
/* Returns total memory in Kb */
|
||||
unsigned long total_memory(void);
|
||||
int ramdisk_possible(unsigned long ramdisk_size);
|
||||
char * get_ramdisk_realname(void);
|
||||
enum return_type load_ramdisk(char *);
|
||||
enum return_type load_ramdisk_fd(int ramdisk_fd, int size);
|
||||
enum return_type load_ramdisk(char *, unsigned long size);
|
||||
enum return_type load_ramdisk_fd(int ramdisk_fd, unsigned long size);
|
||||
void * memdup(void *src, size_t size);
|
||||
void add_to_env(char * name, char * value);
|
||||
void handle_env(char ** env);
|
||||
@ -60,5 +61,6 @@ struct param_elem
|
||||
#define ptr_begins_static_str(pointer,static_str) (!strncmp(pointer,static_str,sizeof(static_str)-1))
|
||||
#define streq !strcmp
|
||||
#define MKDEV(ma,mi) ((ma)<<8 | (mi))
|
||||
#define BYTES2MB(b) ((unsigned int)(b)/1024/1024)
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user