Modernize extfs(8) error handling.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-07-08 15:21:50 +02:00
parent ffc1b02b94
commit edd8566155
2 changed files with 31 additions and 34 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen. * Copyright (c) 2013, 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -22,8 +22,8 @@
#include <assert.h> #include <assert.h>
#include <dirent.h> #include <dirent.h>
#include <err.h>
#include <errno.h> #include <errno.h>
#include <error.h>
#include <fcntl.h> #include <fcntl.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@ -212,7 +212,7 @@ int main(int argc, char* argv[])
read = read || write; read = read || write;
// Default to read and write filesystem access. // Default to read and write filesystem access.
bool default_access = !read && !write ? read = write = true : false; bool default_access = !read && !write ? (read = write = true) : false;
if ( argc == 1 ) if ( argc == 1 )
{ {
@ -236,74 +236,71 @@ int main(int argc, char* argv[])
int fd = open(device_path, write ? O_RDWR : O_RDONLY); int fd = open(device_path, write ? O_RDWR : O_RDONLY);
if ( fd < 0 ) if ( fd < 0 )
error(1, errno, "`%s'", device_path); err(1, "%s", device_path);
// Read the super block from the filesystem so we can verify it. // Read the super block from the filesystem so we can verify it.
struct ext_superblock sb; struct ext_superblock sb;
if ( preadall(fd, &sb, sizeof(sb), 1024) != sizeof(sb) ) if ( preadall(fd, &sb, sizeof(sb), 1024) != sizeof(sb) )
{ {
if ( errno == EEOF ) if ( errno == EEOF )
error(1, 0, "`%s' isn't a valid extended filesystem", device_path); errx(1, "%s: Isn't a valid extended filesystem", device_path);
else else
error(1, errno, "read: `%s'", device_path); err(1, "read: %s", device_path);
} }
// Verify the magic value to detect a compatible filesystem. // Verify the magic value to detect a compatible filesystem.
if ( sb.s_magic != EXT2_SUPER_MAGIC ) if ( sb.s_magic != EXT2_SUPER_MAGIC )
error(1, 0, "`%s' isn't a valid extended filesystem", device_path); errx(1, "%s: Isn't a valid extended filesystem", device_path);
// Test whether this revision of the extended filesystem is supported. // Test whether this revision of the extended filesystem is supported.
if ( sb.s_rev_level == EXT2_GOOD_OLD_REV ) if ( sb.s_rev_level == EXT2_GOOD_OLD_REV )
error(1, 0, "`%s' is formatted with an obsolete filesystem revision", errx(1, "%s: Is formatted with an obsolete filesystem revision",
device_path); device_path);
// Verify that no incompatible features are in use. // Verify that no incompatible features are in use.
if ( sb.s_feature_compat & ~EXT2_FEATURE_INCOMPAT_SUPPORTED ) if ( sb.s_feature_compat & ~EXT2_FEATURE_INCOMPAT_SUPPORTED )
error(1, 0, "`%s' uses unsupported and incompatible features", errx(1, "%s: Uses unsupported and incompatible features", device_path);
device_path);
// Verify that no incompatible features are in use if opening for write. // Verify that no incompatible features are in use if opening for write.
if ( !default_access && write && if ( !default_access && write &&
sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED ) sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
error(1, 0, "`%s' uses unsupported and incompatible features, " errx(1, "%s: Uses unsupported and incompatible features, "
"read-only access is possible, but write-access was " "read-only access is possible, but write-access was requested",
"requested", device_path); device_path);
if ( write && sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED ) if ( write && sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
{ {
fprintf(stderr, "Warning: `%s' uses unsupported and incompatible " warn("warning: %s: Uses unsupported and incompatible features, "
"features, falling back to read-only access\n", "falling back to read-only access\n", device_path);
device_path);
// TODO: Modify the file descriptor such that writing fails! // TODO: Modify the file descriptor such that writing fails!
write = false; write = false;
} }
// Check whether any features are in use that we can safely disregard. // Check whether any features are in use that we can safely disregard.
if ( sb.s_feature_compat & ~EXT2_FEATURE_COMPAT_SUPPORTED ) if ( sb.s_feature_compat & ~EXT2_FEATURE_COMPAT_SUPPORTED )
fprintf(stderr, "Note: filesystem uses unsupported but compatible " warn("%s: Filesystem uses unsupported but compatible features\n",
"features\n"); device_path);
// Check the block size is sane. 64 KiB may have issues, 32 KiB then. // Check the block size is sane. 64 KiB may have issues, 32 KiB then.
if ( sb.s_log_block_size > (15-10) /* 32 KiB blocks */ ) if ( sb.s_log_block_size > (15-10) /* 32 KiB blocks */ )
error(1, 0, "`%s': excess block size", device_path); errx(1, "%s: Filesystem has excess block size", device_path);
// Check whether the filesystem was unmounted cleanly. // Check whether the filesystem was unmounted cleanly.
if ( sb.s_state != EXT2_VALID_FS ) if ( sb.s_state != EXT2_VALID_FS )
fprintf(stderr, "Warning: `%s' wasn't unmounted cleanly\n", warn("warning: %s: Filesystem wasn't unmounted cleanly\n", device_path);
device_path);
uint32_t block_size = 1024U << sb.s_log_block_size; uint32_t block_size = 1024U << sb.s_log_block_size;
Device* dev = new Device(fd, device_path, block_size, write); Device* dev = new Device(fd, device_path, block_size, write);
if ( !dev ) // TODO: Use operator new nothrow! if ( !dev ) // TODO: Use operator new nothrow!
error(1, errno, "malloc"); err(1, "malloc");
Filesystem* fs = new Filesystem(dev, pretend_mount_path); Filesystem* fs = new Filesystem(dev, pretend_mount_path);
if ( !fs ) // TODO: Use operator new nothrow! if ( !fs ) // TODO: Use operator new nothrow!
error(1, errno, "malloc"); err(1, "malloc");
fs->block_groups = new BlockGroup*[fs->num_groups]; fs->block_groups = new BlockGroup*[fs->num_groups];
if ( !fs->block_groups ) // TODO: Use operator new nothrow! if ( !fs->block_groups ) // TODO: Use operator new nothrow!
error(1, errno, "malloc"); err(1, "malloc");
for ( size_t i = 0; i < fs->num_groups; i++ ) for ( size_t i = 0; i < fs->num_groups; i++ )
fs->block_groups[i] = NULL; fs->block_groups[i] = NULL;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2014, 2015, 2016, 2022 Jonas 'Sortie' Termansen. * Copyright (c) 2013, 2014, 2015, 2016, 2022, 2023 Jonas 'Sortie' Termansen.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -24,8 +24,8 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <err.h>
#include <errno.h> #include <errno.h>
#include <error.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <ioleast.h> #include <ioleast.h>
@ -658,8 +658,8 @@ void HandleIncomingMessage(int chl, struct fsm_msg_header* hdr, Filesystem* fs)
if ( (uint16_t) request_uid != request_uid || if ( (uint16_t) request_uid != request_uid ||
(uint16_t) request_gid != request_gid ) (uint16_t) request_gid != request_gid )
{ {
fprintf(stderr, "extfs: id exceeded 16-bit: uid=%ju gid=%ju\n", warn("id exceeded 16-bit: uid=%ju gid=%ju\n",
(uintmax_t) request_uid, (uintmax_t) request_gid); (uintmax_t) request_uid, (uintmax_t) request_gid);
RespondError(chl, EOVERFLOW); RespondError(chl, EOVERFLOW);
return; return;
} }
@ -690,7 +690,7 @@ void HandleIncomingMessage(int chl, struct fsm_msg_header* hdr, Filesystem* fs)
handlers[FSM_REQ_TCGETBLOB] = (handler_t) HandleTCGetBlob; handlers[FSM_REQ_TCGETBLOB] = (handler_t) HandleTCGetBlob;
if ( FSM_MSG_NUM <= hdr->msgtype || !handlers[hdr->msgtype] ) if ( FSM_MSG_NUM <= hdr->msgtype || !handlers[hdr->msgtype] )
{ {
fprintf(stderr, "extfs: message type %zu not supported\n", hdr->msgtype); warn("message type %zu not supported\n", hdr->msgtype);
RespondError(chl, ENOTSUP); RespondError(chl, ENOTSUP);
return; return;
} }
@ -744,14 +744,14 @@ int fsmarshall_main(const char* argv0,
struct stat root_inode_st; struct stat root_inode_st;
Inode* root_inode = fs->GetInode((uint32_t) EXT2_ROOT_INO); Inode* root_inode = fs->GetInode((uint32_t) EXT2_ROOT_INO);
if ( !root_inode ) if ( !root_inode )
error(1, errno, "GetInode(%u)", EXT2_ROOT_INO); err(1, "GetInode(%u)", EXT2_ROOT_INO);
StatInode(root_inode, &root_inode_st); StatInode(root_inode, &root_inode_st);
root_inode->Unref(); root_inode->Unref();
// Create a filesystem server connected to the kernel that we'll listen on. // Create a filesystem server connected to the kernel that we'll listen on.
int serverfd = fsm_mountat(AT_FDCWD, mount_path, &root_inode_st, 0); int serverfd = fsm_mountat(AT_FDCWD, mount_path, &root_inode_st, 0);
if ( serverfd < 0 ) if ( serverfd < 0 )
error(1, errno, "%s", mount_path); err(1, "%s", mount_path);
// Make sure the server isn't unexpectedly killed and data is lost. // Make sure the server isn't unexpectedly killed and data is lost.
signal(SIGINT, TerminationHandler); signal(SIGINT, TerminationHandler);
@ -763,7 +763,7 @@ int fsmarshall_main(const char* argv0,
{ {
pid_t child_pid = fork(); pid_t child_pid = fork();
if ( child_pid < 0 ) if ( child_pid < 0 )
error(1, errno, "fork"); err(1, "fork");
if ( child_pid ) if ( child_pid )
exit(0); exit(0);
setpgid(0, 0); setpgid(0, 0);
@ -785,7 +785,7 @@ int fsmarshall_main(const char* argv0,
size_t amount; size_t amount;
if ( (amount = readall(channel, &hdr, sizeof(hdr))) != sizeof(hdr) ) if ( (amount = readall(channel, &hdr, sizeof(hdr))) != sizeof(hdr) )
{ {
//error(0, errno, "incomplete header: got %zi of %zu bytes", amount, sizeof(hdr)); //warn("incomplete header: got %zi of %zu bytes", amount, sizeof(hdr));
errno = 0; errno = 0;
continue; continue;
} }