Refactor init(8) atexit handling.
This commit is contained in:
parent
fdfe16ad30
commit
0b07e62259
106
init/init.c
106
init/init.c
|
@ -53,6 +53,35 @@
|
||||||
#include <mount/partition.h>
|
#include <mount/partition.h>
|
||||||
#include <mount/uuid.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)
|
static char* read_single_line(FILE* fp)
|
||||||
{
|
{
|
||||||
char* ret = NULL;
|
char* ret = NULL;
|
||||||
|
@ -79,8 +108,6 @@ static char* join_paths(const char* a, const char* b)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pid_t main_pid;
|
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
__attribute__((format(printf, 1, 2)))
|
__attribute__((format(printf, 1, 2)))
|
||||||
static void fatal(const char* format, ...)
|
static void fatal(const char* format, ...)
|
||||||
|
@ -121,10 +148,6 @@ static void note(const char* format, ...)
|
||||||
va_end(ap);
|
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)
|
static void prepare_filesystem(const char* path, struct blockdevice* bdev)
|
||||||
{
|
{
|
||||||
enum filesystem_error fserr = blockdevice_inspect_filesystem(&bdev->fs, 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");
|
fatal("iterating devices: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct device_match
|
|
||||||
{
|
|
||||||
const char* path;
|
|
||||||
struct blockdevice* bdev;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void search_by_uuid(const char* uuid_string,
|
static void search_by_uuid(const char* uuid_string,
|
||||||
void (*cb)(void*, struct device_match*),
|
void (*cb)(void*, struct device_match*),
|
||||||
void* ctx)
|
void* ctx)
|
||||||
|
@ -295,18 +312,6 @@ static void ensure_single_device_match(void* ctx, struct device_match* match)
|
||||||
*result = *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)
|
static int sort_mountpoint(const void* a_ptr, const void* b_ptr)
|
||||||
{
|
{
|
||||||
const struct mountpoint* a = (const struct mountpoint*) a_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)
|
static int init(const char* target)
|
||||||
{
|
{
|
||||||
init_early();
|
init_early();
|
||||||
|
@ -712,8 +740,6 @@ static int init(const char* target)
|
||||||
set_videomode();
|
set_videomode();
|
||||||
prepare_block_devices();
|
prepare_block_devices();
|
||||||
load_fstab();
|
load_fstab();
|
||||||
if ( atexit(mountpoints_unmount) != 0 )
|
|
||||||
fatal("atexit: %m");
|
|
||||||
mountpoints_mount(false);
|
mountpoints_mount(false);
|
||||||
sigset_t oldset, sigttou;
|
sigset_t oldset, sigttou;
|
||||||
sigemptyset(&sigttou);
|
sigemptyset(&sigttou);
|
||||||
|
@ -800,35 +826,14 @@ static int init(const char* target)
|
||||||
else
|
else
|
||||||
note("session: Unexpected unusual termination%s", back);
|
note("session: Unexpected unusual termination%s", back);
|
||||||
}
|
}
|
||||||
mountpoints_unmount();
|
|
||||||
return result;
|
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)
|
static int init_chain(const char* target)
|
||||||
{
|
{
|
||||||
init_early();
|
init_early();
|
||||||
prepare_block_devices();
|
prepare_block_devices();
|
||||||
load_fstab();
|
load_fstab();
|
||||||
if ( atexit(init_chain_atexit) != 0 )
|
|
||||||
fatal("atexit: %m");
|
|
||||||
if ( !mkdtemp(chain_location) )
|
if ( !mkdtemp(chain_location) )
|
||||||
fatal("mkdtemp: /tmp/fs.XXXXXX: %m");
|
fatal("mkdtemp: /tmp/fs.XXXXXX: %m");
|
||||||
chain_location_made = true;
|
chain_location_made = true;
|
||||||
|
@ -844,8 +849,6 @@ static int init_chain(const char* target)
|
||||||
}
|
}
|
||||||
if ( !found_root )
|
if ( !found_root )
|
||||||
fatal("/etc/fstab: Root filesystem not found in filesystem table");
|
fatal("/etc/fstab: Root filesystem not found in filesystem table");
|
||||||
if ( atexit(mountpoints_unmount) != 0 )
|
|
||||||
fatal("atexit: %m");
|
|
||||||
mountpoints_mount(true);
|
mountpoints_mount(true);
|
||||||
snprintf(chain_location_dev, sizeof(chain_location_dev), "%s/dev",
|
snprintf(chain_location_dev, sizeof(chain_location_dev), "%s/dev",
|
||||||
chain_location);
|
chain_location);
|
||||||
|
@ -917,8 +920,6 @@ static int init_chain(const char* target)
|
||||||
else
|
else
|
||||||
note("chain init: Unexpected unusual termination%s", back);
|
note("chain init: Unexpected unusual termination%s", back);
|
||||||
}
|
}
|
||||||
mountpoints_unmount();
|
|
||||||
init_chain_atexit();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -997,6 +998,9 @@ int main(int argc, char* argv[])
|
||||||
if ( getenv("INIT_PID") )
|
if ( getenv("INIT_PID") )
|
||||||
fatal("System is already managed by an init process");
|
fatal("System is already managed by an init process");
|
||||||
|
|
||||||
|
if ( atexit(niht) != 0 )
|
||||||
|
fatal("atexit: %m");
|
||||||
|
|
||||||
if ( !strcmp(target, "single-user") ||
|
if ( !strcmp(target, "single-user") ||
|
||||||
!strcmp(target, "multi-user") ||
|
!strcmp(target, "multi-user") ||
|
||||||
!strcmp(target, "sysinstall") ||
|
!strcmp(target, "sysinstall") ||
|
||||||
|
|
Loading…
Reference in New Issue