network boot: support loading complete ISOs via HTTP
Now I don't have to unpack (or loop mount) ISO to boot via HTTP. Also I can boot directly from any ALT mirror, like this: automatic=method:http,network:dhcp,server:mirror.yandex.ru,directory=/altlinux/images/p9/simply/aarch64/slinux-live-9.1.1-aarch64.iso Closes: #40710
This commit is contained in:
parent
736c89620f
commit
36b688d17a
@ -23,6 +23,7 @@
|
||||
#define IMAGE_LOCATION "/image"
|
||||
#define STAGE2_LOCATION "/root"
|
||||
#define LIVE_DEVICE "/dev/loop0"
|
||||
#define LOMOUNT_DEVICE "/dev/loop3"
|
||||
#define STAGE2FS "squashfs"
|
||||
#define LIVEFS "squashfs"
|
||||
#ifndef STAGE2_BINNAME
|
||||
|
@ -133,7 +133,7 @@ set_loop (const char *device, const char *file)
|
||||
}
|
||||
|
||||
|
||||
char * loopdev = "/dev/loop3"; /* Ugly. But do I care? */
|
||||
char * loopdev = LOMOUNT_DEVICE; /* Ugly. But do I care? */
|
||||
|
||||
void del_loop(char *device)
|
||||
{
|
||||
|
11
network.c
11
network.c
@ -998,6 +998,7 @@ enum return_type http_prepare(void)
|
||||
char *tmp;
|
||||
int fd;
|
||||
unsigned long size;
|
||||
int is_iso = 0;
|
||||
|
||||
snprintf(location_full, sizeof(location_full),
|
||||
"Please enter the name or IP address of the HTTP server, "
|
||||
@ -1009,6 +1010,13 @@ enum return_type http_prepare(void)
|
||||
}
|
||||
|
||||
strcpy(location_full, answers[1]);
|
||||
log_message("HTTP: trying to retrieve %s", location_full);
|
||||
fd = http_download_file(answers[0], location_full, &size);
|
||||
if (fd >= 0) {
|
||||
is_iso = 1;
|
||||
goto download;
|
||||
}
|
||||
|
||||
tmp = get_ramdisk_realname();
|
||||
strcat(location_full, tmp);
|
||||
free(tmp);
|
||||
@ -1026,6 +1034,7 @@ enum return_type http_prepare(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
download:
|
||||
if (!ramdisk_possible(size)) {
|
||||
close(fd);
|
||||
stg1_error_message("HTTP install needs more than %u Mbytes of memory (detected %u Mbytes).",
|
||||
@ -1035,7 +1044,7 @@ enum return_type http_prepare(void)
|
||||
|
||||
log_message("HTTP: size of download %lu bytes", size);
|
||||
|
||||
results = load_ramdisk_fd(fd, size);
|
||||
results = load_ramdisk_or_iso(fd, size, is_iso);
|
||||
close(fd);
|
||||
if (results != RETURN_OK)
|
||||
return RETURN_ERROR;
|
||||
|
70
tools.c
70
tools.c
@ -45,6 +45,7 @@
|
||||
#include "automatic.h"
|
||||
#include <errno.h>
|
||||
#include <linux/loop.h>
|
||||
#include "lomount.h"
|
||||
#include "tools.h"
|
||||
#include "modules.h"
|
||||
#include "sha256.h"
|
||||
@ -297,6 +298,45 @@ static void save_stuff_for_rescue(void)
|
||||
log_message("saved file %s for rescue (%d bytes)", file, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop mount ISO loaded to RAM, and open stage2
|
||||
*
|
||||
* @param ram_fd file descriptor of ISO image
|
||||
* @return file descriptor of stage2 or -1 on error
|
||||
*/
|
||||
static int open_stage2_from_iso(int iso_fd)
|
||||
{
|
||||
int stage2_fd = -1;
|
||||
const char *stage2 = get_ramdisk_path(IMAGE_LOCATION); /* /image/live */
|
||||
if (!stage2) {
|
||||
log_message("%s: get_ramdisk_size: got NULL", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (do_losetup_fd(LOMOUNT_DEVICE, iso_fd, NULL) < 0) {
|
||||
log_message("%s: could not setup loopback for iso_fd", __func__);
|
||||
goto out_free;
|
||||
}
|
||||
if (my_mount(LOMOUNT_DEVICE, IMAGE_LOCATION, "iso9660", 0)) {
|
||||
log_message("%s: failed to mount ISO loopback", __func__);
|
||||
goto out_del_loop;
|
||||
}
|
||||
stage2_fd = open(stage2, O_RDONLY);
|
||||
if (stage2_fd < 0) {
|
||||
log_message("%s: failed to open %s", __func__, stage2);
|
||||
goto out_umount;
|
||||
}
|
||||
free((char *)stage2);
|
||||
return stage2_fd;
|
||||
|
||||
out_umount:
|
||||
umount(IMAGE_LOCATION);
|
||||
out_del_loop:
|
||||
del_loop(LOMOUNT_DEVICE);
|
||||
out_free:
|
||||
free((char *)stage2);
|
||||
out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief copy exactly len bytes from buffer to file descriptor
|
||||
@ -382,7 +422,7 @@ out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
enum return_type load_ramdisk_fd(int source_fd, unsigned long size)
|
||||
enum return_type load_ramdisk_or_iso(int source_fd, unsigned long size, int is_iso)
|
||||
{
|
||||
int ram_fd;
|
||||
char * wait_msg = "Loading program into memory...";
|
||||
@ -405,8 +445,26 @@ enum return_type load_ramdisk_fd(int source_fd, unsigned long size)
|
||||
}
|
||||
end_progression();
|
||||
|
||||
if (is_iso) {
|
||||
int stage2_fd = open_stage2_from_iso(ram_fd);
|
||||
if (stage2_fd < 0) {
|
||||
close(ram_fd);
|
||||
stg1_error_message("Could not open stage2 from ISO in RAM");
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
/* got a (mounted) loopback device backed by ram_fd,
|
||||
* ram_fd itself is not necessary any more */
|
||||
close(ram_fd);
|
||||
/* to setup loopback device from stage2_fd */
|
||||
ram_fd = stage2_fd;
|
||||
}
|
||||
|
||||
if (do_losetup_fd(LIVE_DEVICE, ram_fd, NULL) < 0) {
|
||||
close(ram_fd);
|
||||
if (is_iso) {
|
||||
umount(IMAGE_LOCATION);
|
||||
del_loop(LOMOUNT_DEVICE);
|
||||
}
|
||||
stg1_error_message("Could not setup loopback for 2nd stage");
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
@ -416,6 +474,10 @@ enum return_type load_ramdisk_fd(int source_fd, unsigned long size)
|
||||
|
||||
if (my_mount(LIVE_DEVICE, STAGE2_LOCATION, STAGE2FS, 0)) {
|
||||
stg1_error_message("Failed to mount stage2");
|
||||
if (is_iso) {
|
||||
umount(IMAGE_LOCATION);
|
||||
del_loop(LOMOUNT_DEVICE);
|
||||
}
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
|
||||
@ -427,12 +489,18 @@ enum return_type load_ramdisk_fd(int source_fd, unsigned long size)
|
||||
log_message("rescue: failed to umount " STAGE2_LOCATION);
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
if (is_iso) {
|
||||
/* XXX: should I do anything special here? */
|
||||
}
|
||||
return RETURN_OK; /* fucksike, I lost several hours wondering why the kernel won't see the rescue if it is alreay mounted */
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
enum return_type load_ramdisk_fd(int source_fd, unsigned long size) {
|
||||
return load_ramdisk_or_iso(source_fd, size, 0);
|
||||
}
|
||||
|
||||
int splash_verbose()
|
||||
{
|
||||
|
1
tools.h
1
tools.h
@ -36,6 +36,7 @@ int ramdisk_possible(unsigned long ramdisk_size);
|
||||
char * get_ramdisk_realname(void);
|
||||
enum return_type load_ramdisk(char *, unsigned long size);
|
||||
enum return_type load_ramdisk_fd(int ramdisk_fd, unsigned long size);
|
||||
enum return_type load_ramdisk_or_iso(int ramdisk_fd, unsigned long size, int is_iso);
|
||||
void * memdup(void *src, size_t size);
|
||||
void add_to_env(char * name, char * value);
|
||||
void handle_env(char ** env);
|
||||
|
Loading…
Reference in New Issue
Block a user