mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Check architecture compatibility during sysmerge(8)/sysupgrade(8).
This commit is contained in:
parent
cd7a984e9f
commit
ce6ea7f553
4 changed files with 107 additions and 10 deletions
|
@ -17,6 +17,7 @@
|
|||
* File operation utility functions.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
|
@ -129,3 +130,42 @@ void write_random_seed(const char* path)
|
|||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
char* read_string_file(const char* path)
|
||||
{
|
||||
FILE* fp = fopen(path, "r");
|
||||
if ( !fp )
|
||||
return NULL;
|
||||
struct stat st;
|
||||
if ( fstat(fileno(fp), &st) < 0 )
|
||||
{
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
size_t content_length;
|
||||
if ( __builtin_add_overflow(1, st.st_size, &content_length) )
|
||||
{
|
||||
fclose(fp);
|
||||
errno = EOVERFLOW;
|
||||
return NULL;
|
||||
}
|
||||
char* content = malloc(content_length);
|
||||
if ( !content )
|
||||
{
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
size_t amount = fread(content, 1, content_length - 1, fp);
|
||||
if ( ferror(fp) )
|
||||
{
|
||||
fclose(fp);
|
||||
free(content);
|
||||
return NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
if ( 0 < amount && content[amount - 1] == '\n' )
|
||||
content[amount - 1] = '\0';
|
||||
else
|
||||
content[amount] = '\0';
|
||||
return content;
|
||||
}
|
||||
|
|
|
@ -25,5 +25,6 @@ int mkdir_p(const char* path, mode_t mode);
|
|||
int access_or_die(const char* path, int mode);
|
||||
void mkdir_or_chmod_or_die(const char* path, mode_t mode);
|
||||
void write_random_seed(const char* path);
|
||||
char* read_string_file(const char* path);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -191,7 +191,23 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
free(new_release_path);
|
||||
|
||||
// TODO: Check if /etc/machine matches the current architecture.
|
||||
const char* old_machine_path = "/etc/machine";
|
||||
char* old_machine = read_string_file(old_machine_path);
|
||||
if ( !old_machine )
|
||||
err(2, "%s", old_machine_path);
|
||||
char* new_machine_path;
|
||||
if ( asprintf(&new_machine_path, "%s/etc/machine", source) < 0 )
|
||||
err(2, "asprintf");
|
||||
char* new_machine = read_string_file(new_machine_path);
|
||||
if ( !new_machine )
|
||||
err(2, "%s", new_machine_path);
|
||||
if ( strcmp(old_machine, new_machine) != 0 )
|
||||
errx(2, "%s (%s) does not match %s (%s)", new_machine_path,
|
||||
new_machine, old_machine_path, old_machine);
|
||||
free(old_machine);
|
||||
free(new_machine_path);
|
||||
free(new_machine);
|
||||
|
||||
// TODO: Check for version (skipping, downgrading).
|
||||
|
||||
struct conf conf;
|
||||
|
|
|
@ -60,6 +60,7 @@ struct installation
|
|||
struct release release;
|
||||
struct mountpoint* mountpoints;
|
||||
size_t mountpoints_used;
|
||||
char* machine;
|
||||
};
|
||||
|
||||
static struct installation* installations;
|
||||
|
@ -74,7 +75,8 @@ static char fs[] = "/tmp/fs.XXXXXX";
|
|||
static bool add_installation(struct blockdevice* bdev,
|
||||
struct release* release,
|
||||
struct mountpoint* mountpoints,
|
||||
size_t mountpoints_used)
|
||||
size_t mountpoints_used,
|
||||
char* machine)
|
||||
{
|
||||
if ( installations_count == installations_length )
|
||||
{
|
||||
|
@ -93,6 +95,7 @@ static bool add_installation(struct blockdevice* bdev,
|
|||
installation->release = *release;
|
||||
installation->mountpoints = mountpoints;
|
||||
installation->mountpoints_used = mountpoints_used;
|
||||
installation->machine = machine;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -135,7 +138,23 @@ static void search_installation_path(const char* mnt, struct blockdevice* bdev)
|
|||
release_free(&release);
|
||||
return;
|
||||
}
|
||||
if ( !add_installation(bdev, &release, mountpoints, mountpoints_used) )
|
||||
char* machine_path;
|
||||
if ( asprintf(&machine_path, "%s/etc/machine", mnt) < 0 )
|
||||
{
|
||||
warn("%s: malloc", path_of_blockdevice(bdev));
|
||||
release_free(&release);
|
||||
return;
|
||||
}
|
||||
char* machine = read_string_file(machine_path);
|
||||
free(machine_path);
|
||||
if ( !machine )
|
||||
{
|
||||
warn("%s/etc/machine", path_of_blockdevice(bdev));
|
||||
release_free(&release);
|
||||
return;
|
||||
}
|
||||
if ( !add_installation(bdev, &release, mountpoints, mountpoints_used,
|
||||
machine) )
|
||||
{
|
||||
free_mountpoints(mountpoints, mountpoints_used);
|
||||
release_free(&release);
|
||||
|
@ -516,9 +535,10 @@ int main(void)
|
|||
for ( size_t i = 0; i < installations_count; i++ )
|
||||
{
|
||||
struct installation* installation = &installations[i];
|
||||
printf(" %-16s %s\n",
|
||||
printf(" %-16s %s (%s)\n",
|
||||
path_of_blockdevice(installation->bdev),
|
||||
installation->release.pretty_name);
|
||||
installation->release.pretty_name,
|
||||
installation->machine);
|
||||
}
|
||||
text("\n");
|
||||
|
||||
|
@ -549,7 +569,27 @@ int main(void)
|
|||
|
||||
struct release* target_release = &target->release;
|
||||
|
||||
// TODO: Check if /etc/machine matches the current architecture.
|
||||
char* source_machine = read_string_file("/etc/machine");
|
||||
if ( !source_machine )
|
||||
err(2, "/etc/machine");
|
||||
if ( strcmp(target->machine, source_machine) != 0 )
|
||||
{
|
||||
textf("Warning: You are changing an existing installation to another "
|
||||
"architecture! (%s -> %s) This is not supported and there is no "
|
||||
"promise this will work!\n", target->machine, source_machine);
|
||||
while ( true )
|
||||
{
|
||||
prompt(input, sizeof(input),
|
||||
"Change the existing installation to another architecture?",
|
||||
"no");
|
||||
if ( !strcasecmp(input, "no") || !strcasecmp(input, "yes") )
|
||||
break;
|
||||
}
|
||||
if ( !strcasecmp(input, "no") )
|
||||
errx(2, "upgrade aborted because of architecture mismatch");
|
||||
text("\n");
|
||||
}
|
||||
free(source_machine);
|
||||
|
||||
if ( downgrading_version(target_release, &new_release) )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue