mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Refactor init(8) atexit handling.
This commit is contained in:
parent
ae72ebaa98
commit
c1e66b168b
1 changed files with 55 additions and 51 deletions
106
init/init.c
106
init/init.c
|
@ -53,6 +53,35 @@
|
|||
#include <mount/partition.h>
|
||||
#include <mount/uuid.h>
|
||||
|
||||
struct device_match
|
||||
{
|
||||
const char* path;
|
||||
struct blockdevice* bdev;
|
||||
};
|
||||
|
||||
struct mountpoint
|
||||
{
|
||||
struct fstab entry;
|
||||
char* entry_line;
|
||||
pid_t pid;
|
||||
char* absolute;
|
||||
};
|
||||
|
||||
static pid_t main_pid;
|
||||
|
||||
static struct harddisk** hds = NULL;
|
||||
static size_t hds_used = 0;
|
||||
static size_t hds_length = 0;
|
||||
|
||||
static struct mountpoint* mountpoints = NULL;
|
||||
static size_t mountpoints_used = 0;
|
||||
static size_t mountpoints_length = 0;
|
||||
|
||||
static bool chain_location_made = false;
|
||||
static char chain_location[] = "/tmp/fs.XXXXXX";
|
||||
static bool chain_location_dev_made = false;
|
||||
static char chain_location_dev[] = "/tmp/fs.XXXXXX/dev";
|
||||
|
||||
static char* read_single_line(FILE* fp)
|
||||
{
|
||||
char* ret = NULL;
|
||||
|
@ -79,8 +108,6 @@ static char* join_paths(const char* a, const char* b)
|
|||
return result;
|
||||
}
|
||||
|
||||
static pid_t main_pid;
|
||||
|
||||
__attribute__((noreturn))
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
static void fatal(const char* format, ...)
|
||||
|
@ -121,10 +148,6 @@ static void note(const char* format, ...)
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
static struct harddisk** hds = NULL;
|
||||
static size_t hds_used = 0;
|
||||
static size_t hds_length = 0;
|
||||
|
||||
static void prepare_filesystem(const char* path, struct blockdevice* bdev)
|
||||
{
|
||||
enum filesystem_error fserr = blockdevice_inspect_filesystem(&bdev->fs, bdev);
|
||||
|
@ -233,12 +256,6 @@ static void prepare_block_devices(void)
|
|||
fatal("iterating devices: %m");
|
||||
}
|
||||
|
||||
struct device_match
|
||||
{
|
||||
const char* path;
|
||||
struct blockdevice* bdev;
|
||||
};
|
||||
|
||||
static void search_by_uuid(const char* uuid_string,
|
||||
void (*cb)(void*, struct device_match*),
|
||||
void* ctx)
|
||||
|
@ -295,18 +312,6 @@ static void ensure_single_device_match(void* ctx, struct device_match* match)
|
|||
*result = *match;
|
||||
}
|
||||
|
||||
struct mountpoint
|
||||
{
|
||||
struct fstab entry;
|
||||
char* entry_line;
|
||||
pid_t pid;
|
||||
char* absolute;
|
||||
};
|
||||
|
||||
static struct mountpoint* mountpoints = NULL;
|
||||
static size_t mountpoints_used = 0;
|
||||
static size_t mountpoints_length = 0;
|
||||
|
||||
static int sort_mountpoint(const void* a_ptr, const void* b_ptr)
|
||||
{
|
||||
const struct mountpoint* a = (const struct mountpoint*) a_ptr;
|
||||
|
@ -704,6 +709,29 @@ static void mountpoints_unmount(void)
|
|||
}
|
||||
}
|
||||
|
||||
// This function must be usable as an atexit handler, which means it is
|
||||
// undefined behavior for it to invoke exit(), including through calls to fatal
|
||||
// in any function transitively called by this function.
|
||||
static void niht(void)
|
||||
{
|
||||
if ( getpid() != main_pid )
|
||||
return;
|
||||
|
||||
if ( chain_location_dev_made )
|
||||
{
|
||||
unmount(chain_location_dev, 0);
|
||||
chain_location_dev_made = false;
|
||||
}
|
||||
|
||||
mountpoints_unmount();
|
||||
|
||||
if ( chain_location_made )
|
||||
{
|
||||
rmdir(chain_location);
|
||||
chain_location_made = false;
|
||||
}
|
||||
}
|
||||
|
||||
static int init(const char* target)
|
||||
{
|
||||
init_early();
|
||||
|
@ -712,8 +740,6 @@ static int init(const char* target)
|
|||
set_videomode();
|
||||
prepare_block_devices();
|
||||
load_fstab();
|
||||
if ( atexit(mountpoints_unmount) != 0 )
|
||||
fatal("atexit: %m");
|
||||
mountpoints_mount(false);
|
||||
sigset_t oldset, sigttou;
|
||||
sigemptyset(&sigttou);
|
||||
|
@ -800,35 +826,14 @@ static int init(const char* target)
|
|||
else
|
||||
note("session: Unexpected unusual termination%s", back);
|
||||
}
|
||||
mountpoints_unmount();
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool chain_location_made = false;
|
||||
static char chain_location[] = "/tmp/fs.XXXXXX";
|
||||
static bool chain_location_dev_made = false;
|
||||
static char chain_location_dev[] = "/tmp/fs.XXXXXX/dev";
|
||||
static void init_chain_atexit(void)
|
||||
{
|
||||
if ( chain_location_dev_made )
|
||||
{
|
||||
unmount(chain_location_dev, 0);
|
||||
chain_location_dev_made = false;
|
||||
}
|
||||
if ( chain_location_made )
|
||||
{
|
||||
rmdir(chain_location);
|
||||
chain_location_made = false;
|
||||
}
|
||||
}
|
||||
|
||||
static int init_chain(const char* target)
|
||||
{
|
||||
init_early();
|
||||
prepare_block_devices();
|
||||
load_fstab();
|
||||
if ( atexit(init_chain_atexit) != 0 )
|
||||
fatal("atexit: %m");
|
||||
if ( !mkdtemp(chain_location) )
|
||||
fatal("mkdtemp: /tmp/fs.XXXXXX: %m");
|
||||
chain_location_made = true;
|
||||
|
@ -844,8 +849,6 @@ static int init_chain(const char* target)
|
|||
}
|
||||
if ( !found_root )
|
||||
fatal("/etc/fstab: Root filesystem not found in filesystem table");
|
||||
if ( atexit(mountpoints_unmount) != 0 )
|
||||
fatal("atexit: %m");
|
||||
mountpoints_mount(true);
|
||||
snprintf(chain_location_dev, sizeof(chain_location_dev), "%s/dev",
|
||||
chain_location);
|
||||
|
@ -917,8 +920,6 @@ static int init_chain(const char* target)
|
|||
else
|
||||
note("chain init: Unexpected unusual termination%s", back);
|
||||
}
|
||||
mountpoints_unmount();
|
||||
init_chain_atexit();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -997,6 +998,9 @@ int main(int argc, char* argv[])
|
|||
if ( getenv("INIT_PID") )
|
||||
fatal("System is already managed by an init process");
|
||||
|
||||
if ( atexit(niht) != 0 )
|
||||
fatal("atexit: %m");
|
||||
|
||||
if ( !strcmp(target, "single-user") ||
|
||||
!strcmp(target, "multi-user") ||
|
||||
!strcmp(target, "sysinstall") ||
|
||||
|
|
Loading…
Reference in a new issue