Recognize read-only block devices.
Add tcgetblob(2) harddisk-writable key that says whether a block device is writable. Prefer writable block devices in disked(8). Ignore read-only block devices in sysinstall(8) and sysupgrade(8) when searching for existing installations and other operating systems. This is a compatible ABI change.
This commit is contained in:
parent
74f12febba
commit
03e8ed9415
19 changed files with 94 additions and 25 deletions
2
Makefile
2
Makefile
|
@ -283,7 +283,7 @@ sysroot-system: sysroot-fsh sysroot-base-headers
|
|||
echo 'ID=sortix' && \
|
||||
echo 'VERSION_ID="$(VERSION)"' && \
|
||||
echo 'PRETTY_NAME="Sortix $(VERSION)"' && \
|
||||
echo 'SORTIX_ABI=2.1' && \
|
||||
echo 'SORTIX_ABI=2.2' && \
|
||||
true) > "$(SYSROOT)/etc/sortix-release"
|
||||
echo /etc/sortix-release >> "$(SYSROOT)/tix/manifest/system"
|
||||
ln -sf sortix-release "$(SYSROOT)/etc/os-release"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2017, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -494,10 +494,14 @@ static void remove_partition_devices(const char* path)
|
|||
free(dir_path);
|
||||
}
|
||||
|
||||
static int harddisk_compare_path(const void* a_ptr, const void* b_ptr)
|
||||
static int harddisk_compare(const void* a_ptr, const void* b_ptr)
|
||||
{
|
||||
struct harddisk* a = *((struct harddisk**) a_ptr);
|
||||
struct harddisk* b = *((struct harddisk**) b_ptr);
|
||||
if ( a->writable && !b->writable )
|
||||
return -1;
|
||||
if ( !a->writable && b->writable )
|
||||
return 1;
|
||||
return strcmp(a->path, b->path);
|
||||
}
|
||||
|
||||
|
@ -1371,7 +1375,7 @@ static void on_devices(size_t argc, char** argv)
|
|||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
qsort(hds, hds_count, sizeof(struct harddisk*), harddisk_compare_path);
|
||||
qsort(hds, hds_count, sizeof(struct harddisk*), harddisk_compare);
|
||||
display_rows_columns(display_harddisk_format, hds, 1 + hds_count, 5);
|
||||
}
|
||||
|
||||
|
@ -2870,7 +2874,7 @@ int main(int argc, char* argv[])
|
|||
if ( !devices_open_all(&hds, &hds_count) )
|
||||
err(1, "iterating devices");
|
||||
|
||||
qsort(hds, hds_count, sizeof(struct harddisk*), harddisk_compare_path);
|
||||
qsort(hds, hds_count, sizeof(struct harddisk*), harddisk_compare);
|
||||
|
||||
if ( 2 <= argc )
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2024 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -4310,7 +4310,10 @@ static bool mountpoint_mount(struct mountpoint* mountpoint)
|
|||
const char* pretend_where = mountpoint->entry.fs_file;
|
||||
const char* where = mountpoint->absolute;
|
||||
const char* read_only = NULL;
|
||||
if ( fs->flags & (FILESYSTEM_FLAG_FSCK_SHOULD | FILESYSTEM_FLAG_FSCK_MUST) )
|
||||
if ( !(fs->flags & FILESYSTEM_FLAG_WRITABLE) )
|
||||
read_only = "-r";
|
||||
else if ( fs->flags & (FILESYSTEM_FLAG_FSCK_SHOULD |
|
||||
FILESYSTEM_FLAG_FSCK_MUST) )
|
||||
{
|
||||
if ( !fsck(fs) && (fs->flags & FILESYSTEM_FLAG_FSCK_MUST) )
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2014, 2015, 2016, 2021, 2024 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2013, 2014, 2015, 2016, 2021, 2024, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -552,6 +552,11 @@ const unsigned char* Port::GetATAIdentify(size_t* size_ptr)
|
|||
return *size_ptr = sizeof(identify_data), identify_data;
|
||||
}
|
||||
|
||||
bool Port::IsWritable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Port::sync(ioctx_t* ctx)
|
||||
{
|
||||
(void) ctx;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2013, 2014, 2015, 2016, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -59,6 +59,7 @@ public:
|
|||
virtual const char* GetSerial();
|
||||
virtual const char* GetRevision();
|
||||
virtual const unsigned char* GetATAIdentify(size_t* size_ptr);
|
||||
virtual bool IsWritable();
|
||||
virtual int sync(ioctx_t* ctx);
|
||||
virtual ssize_t pread(ioctx_t* ctx, unsigned char* buf, size_t count, off_t off);
|
||||
virtual ssize_t pwrite(ioctx_t* ctx, const unsigned char* buf, size_t count, off_t off);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2016, 2018, 2021, 2024 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2016, 2018, 2021-2022, 2024-2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -681,6 +681,11 @@ const unsigned char* Port::GetATAIdentify(size_t* size_ptr)
|
|||
return *size_ptr = sizeof(identify_data), identify_data;
|
||||
}
|
||||
|
||||
bool Port::IsWritable()
|
||||
{
|
||||
return !is_packet_interface;
|
||||
}
|
||||
|
||||
int Port::sync(ioctx_t* ctx)
|
||||
{
|
||||
if ( is_packet_interface )
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2016, 2018, 2021 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2016, 2018, 2021, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -54,6 +54,7 @@ public:
|
|||
virtual const char* GetSerial();
|
||||
virtual const char* GetRevision();
|
||||
virtual const unsigned char* GetATAIdentify(size_t* size_ptr);
|
||||
virtual bool IsWritable();
|
||||
virtual int sync(ioctx_t* ctx);
|
||||
virtual ssize_t pread(ioctx_t* ctx, unsigned char* buf, size_t count, off_t off);
|
||||
virtual ssize_t pwrite(ioctx_t* ctx, const unsigned char* buf, size_t count, off_t off);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2017 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2017, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -103,7 +103,8 @@ ssize_t PortNode::tcgetblob(ioctx_t* ctx, const char* name, void* buffer,
|
|||
"harddisk-cylinders\0"
|
||||
"harddisk-heads\0"
|
||||
"harddisk-sectors\0"
|
||||
"harddisk-ata-identify\0";
|
||||
"harddisk-ata-identify\0"
|
||||
"harddisk-writable\0";
|
||||
|
||||
if ( !name )
|
||||
{
|
||||
|
@ -171,6 +172,11 @@ ssize_t PortNode::tcgetblob(ioctx_t* ctx, const char* name, void* buffer,
|
|||
if ( !(result_pointer = harddisk->GetATAIdentify(&result_size)) )
|
||||
return -1;
|
||||
}
|
||||
else if ( !strcmp(name, "harddisk-writable") )
|
||||
{
|
||||
result_pointer = harddisk->IsWritable() ? "true" : "false";
|
||||
result_size = strlen((const char*) result_pointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
return errno = ENOENT, -1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -41,6 +41,7 @@ public:
|
|||
virtual const char* GetSerial() = 0;
|
||||
virtual const char* GetRevision() = 0;
|
||||
virtual const unsigned char* GetATAIdentify(size_t* size_ptr) = 0;
|
||||
virtual bool IsWritable() = 0;
|
||||
virtual int sync(ioctx_t* ctx) = 0;
|
||||
virtual ssize_t pread(ioctx_t* ctx, unsigned char* buf, size_t count, off_t off) = 0;
|
||||
virtual ssize_t pwrite(ioctx_t* ctx, const unsigned char* buf, size_t count, off_t off) = 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -30,6 +30,14 @@
|
|||
#include <mount/harddisk.h>
|
||||
#include <mount/partition.h>
|
||||
|
||||
bool blockdevice_is_writable(const struct blockdevice* bdev)
|
||||
{
|
||||
while ( bdev->p )
|
||||
bdev = bdev->p->parent_bdev;
|
||||
assert(bdev->hd);
|
||||
return bdev->hd->writable;
|
||||
}
|
||||
|
||||
blksize_t blockdevice_logical_block_size(const struct blockdevice* bdev)
|
||||
{
|
||||
while ( bdev->p )
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -150,6 +150,9 @@ static enum filesystem_error ext2_inspect(struct filesystem** fs_ptr,
|
|||
fs->driver = "extfs";
|
||||
if ( sb->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPPORTED )
|
||||
fs->driver = NULL;
|
||||
else if ( !(sb->s_feature_compat & ~EXT2_FEATURE_COMPAT_SUPPORTED) &&
|
||||
blockdevice_is_writable(bdev) )
|
||||
fs->flags |= FILESYSTEM_FLAG_WRITABLE;
|
||||
fs->flags |= FILESYSTEM_FLAG_UUID;
|
||||
memcpy(&fs->uuid, sb->s_uuid, 16);
|
||||
struct timespec now;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2021 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2021, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -97,6 +97,10 @@ bool harddisk_inspect_blockdevice(struct harddisk* hd)
|
|||
return harddisk_close(hd), false;
|
||||
hd->sectors = (uint16_t) strtoul(str, NULL, 10);
|
||||
free(str);
|
||||
if ( !(str = atcgetblob(hd->fd, "harddisk-writable", NULL)) )
|
||||
return harddisk_close(hd), false;
|
||||
hd->writable = !strcmp(str, "true");
|
||||
free(str);
|
||||
if ( !hd->logical_block_size )
|
||||
return errno = ENOMEDIUM, false;
|
||||
// TODO: To avoid potential overflow bugs (assuming malicious filesystem),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -49,6 +49,7 @@ struct blockdevice
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool blockdevice_is_writable(const struct blockdevice*);
|
||||
blksize_t blockdevice_logical_block_size(const struct blockdevice*);
|
||||
bool blockdevice_check_reasonable_block_size(blksize_t);
|
||||
off_t blockdevice_size(const struct blockdevice*);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -36,6 +36,7 @@ struct filesystem_handler;
|
|||
#define FILESYSTEM_FLAG_FSCK_SHOULD (1 << 1)
|
||||
#define FILESYSTEM_FLAG_FSCK_MUST (1 << 2)
|
||||
#define FILESYSTEM_FLAG_NOT_FILESYSTEM (1 << 3)
|
||||
#define FILESYSTEM_FLAG_WRITABLE (1 << 4)
|
||||
|
||||
struct filesystem
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -43,6 +43,7 @@ struct harddisk
|
|||
uint16_t cylinders;
|
||||
uint16_t heads;
|
||||
uint16_t sectors;
|
||||
bool writable;
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -69,6 +69,13 @@ releasing Sortix x.y, foo." to allow the maintainer to easily
|
|||
.Xr grep 1
|
||||
for it after a release.
|
||||
.Sh CHANGES
|
||||
.Ss Recognize read-only block devices
|
||||
The
|
||||
.Xr tcgetblob 2
|
||||
system call has gained the new
|
||||
.Sy harddisk-writable
|
||||
key, which returns whether a block device is writable.
|
||||
This is a minor compatible ABI change.
|
||||
.Ss Add tix-repository(8)
|
||||
The new
|
||||
.Xr tix-repository 8
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 2021, 2022 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2021, 2022, 2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -190,7 +190,17 @@ bool check_lacking_partition_table(void)
|
|||
|
||||
bool check_multiple_harddisks(void)
|
||||
{
|
||||
return 2 <= hds_count;
|
||||
bool any_writable = false;
|
||||
for ( size_t di = 0; di < hds_count; di++ )
|
||||
{
|
||||
if ( hds[di]->writable )
|
||||
{
|
||||
if ( any_writable )
|
||||
return true;
|
||||
any_writable = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fsck(struct filesystem* fs)
|
||||
|
@ -332,6 +342,9 @@ bool mountpoint_mount(struct mountpoint* mountpoint)
|
|||
struct blockdevice* bdev = fs->bdev;
|
||||
const char* bdev_path = path_of_blockdevice(bdev);
|
||||
assert(bdev_path);
|
||||
const char* read_only = NULL;
|
||||
if ( !(fs->flags & FILESYSTEM_FLAG_WRITABLE) )
|
||||
read_only = "-r";
|
||||
if ( fs->flags & FILESYSTEM_FLAG_FSCK_MUST && !fsck(fs) )
|
||||
{
|
||||
warnx("Failed to fsck %s", bdev_path);
|
||||
|
@ -378,7 +391,8 @@ bool mountpoint_mount(struct mountpoint* mountpoint)
|
|||
_exit(127);
|
||||
}
|
||||
execlp(fs->driver, fs->driver, "--foreground", bdev_path, where,
|
||||
"--pretend-mount-path", pretend_where, (const char*) NULL);
|
||||
"--pretend-mount-path", pretend_where, read_only,
|
||||
(const char*) NULL);
|
||||
warn("Failed mount %s on %s: execvp: %s",
|
||||
bdev_path, pretend_where, fs->driver);
|
||||
_exit(127);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 2020, 2021, 2022, 2023 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015-2016, 2020-2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -192,6 +192,8 @@ static bool should_install_bootloader(void)
|
|||
for ( size_t i = 0; i < hds_count; i++ )
|
||||
{
|
||||
struct harddisk* hd = hds[i];
|
||||
if ( !hd->writable )
|
||||
continue;
|
||||
if ( hd->bdev.pt )
|
||||
{
|
||||
for ( size_t n = 0; n < hd->bdev.pt->partitions_count; n++ )
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 2020, 2021 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015-2016, 2020-2025 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -199,6 +199,8 @@ static void search_installations(const char* mnt)
|
|||
for ( size_t i = 0; i < hds_count; i++ )
|
||||
{
|
||||
struct harddisk* hd = hds[i];
|
||||
if ( !hd->writable )
|
||||
continue;
|
||||
if ( hd->bdev.pt )
|
||||
{
|
||||
for ( size_t n = 0; n < hd->bdev.pt->partitions_count; n++ )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue