diff --git a/src/ccmodules/fbootcmd.c b/src/ccmodules/fbootcmd.c index 3f7f9dd..497d688 100644 --- a/src/ccmodules/fbootcmd.c +++ b/src/ccmodules/fbootcmd.c @@ -55,11 +55,9 @@ static void fbootcmd_item(GNode* node, gpointer command_line) { } void fbootcmd_handler(GNode *node) { - bool firstboot; GString* command_line = NULL; LOG(MOD "fbootcmd handler running...\n"); - get_boot_info(&firstboot, NULL); - if (firstboot) { + if (is_first_boot()) { LOG(MOD "Running first boot commands\n"); command_line = g_string_new(""); g_node_children_foreach(node, G_TRAVERSE_ALL, fbootcmd_item, command_line); diff --git a/src/datasources/openstack.c b/src/datasources/openstack.c index 5823881..7cca9e4 100644 --- a/src/datasources/openstack.c +++ b/src/datasources/openstack.c @@ -147,10 +147,10 @@ bool openstack_init(bool no_network) { return true; } - if (no_network) { - LOG(MOD "config drive was not found and --no-network option was used\n"); - return false; - } + if (no_network) { + LOG(MOD "config drive was not found and --no-network option was used\n"); + return false; + } if (!curl_common_init(&curl)) { LOG(MOD "Curl initialize failed\n"); @@ -426,7 +426,7 @@ static void openstack_run_handler(GNode *node, __unused__ gpointer null) { static void openstack_process_uuid(GNode* node, __unused__ gpointer *data) { if (node->data && g_strcmp0(node->data, "uuid") == 0) { openstack_metadata_uuid(node->children); - g_node_unlink(node); + g_node_unlink(node); g_node_destroy(node); } } @@ -456,9 +456,7 @@ static int openstack_metadata_keys(GNode* node) { static int openstack_metadata_hostname(GNode* node) { gchar command[LINE_MAX]; - bool firstboot = false; - get_boot_info(&firstboot, NULL); - if (firstboot) { + if (is_first_boot()) { g_snprintf(command, LINE_MAX, HOSTNAMECTL_PATH " set-hostname '%s'", (char*)node->data); return exec_task(command); } diff --git a/src/lib.c b/src/lib.c index fb551bc..5f80c30 100644 --- a/src/lib.c +++ b/src/lib.c @@ -65,7 +65,10 @@ #define LOOP_MAJOR_ID 7 #define SUDOERS_PATH SYSCONFDIR "/sudoers.d/" #define INSTANCE_ID_FILE DATADIR_PATH "/instance-id" -#define LAST_INSTANCE_ID_FILE DATADIR_PATH "/last-instance-id" +#define FIRST_BOOT_ID_FILE DATADIR_PATH "/first-boot-id" +#define KERNEL_BOOT_ID_FILE "/proc/sys/kernel/random/boot_id" + +G_LOCK_DEFINE(first_boot_id_file); void LOG(const char *fmt, ...) { @@ -518,89 +521,74 @@ bool umount_filesystem(const gchar* mountdir, const gchar* loop_device) { return true; } -bool save_instance_id(const gchar* instance_id) { - GString* id = g_string_new(instance_id); - - LOG(MOD "Saving instance id '%s'\n", id->str); - - if (!write_file(id, INSTANCE_ID_FILE, O_CREAT|O_TRUNC|O_WRONLY, S_IRWXU)) { - LOG(MOD "Unable to save instance id\n"); - g_string_free(id, true); - return false; - } - - g_string_free(id, true); - return true; -} - -void get_boot_info(bool* firstboot, bool* snapshot) { - gchar* instance_id = NULL; +bool save_instance_id(const gchar* id) { + bool result = false; + GString* instance_id = g_string_new(id); gchar* last_instance_id = NULL; struct stat st; - static int cache_firstboot = -1; - static int cache_snapshot = -1; - if (cache_firstboot != -1 && cache_snapshot != -1 ) { - if (snapshot) { - *snapshot = (bool)cache_snapshot; + if (stat(INSTANCE_ID_FILE, &st) != 0) { + if (!write_file(instance_id, INSTANCE_ID_FILE, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) { + LOG(MOD "Unable to save instance id\n"); + goto exit; } - if (firstboot) { - *firstboot = (bool)cache_firstboot; + } else { + if (!g_file_get_contents(INSTANCE_ID_FILE, &last_instance_id, NULL, NULL)) { + LOG(MOD "Unable to read file '%s'\n", INSTANCE_ID_FILE); + goto exit; + } + if (g_strcmp0(instance_id->str, last_instance_id) != 0) { + g_free(last_instance_id); + if (!write_file(instance_id, INSTANCE_ID_FILE, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) { + LOG(MOD "Unable to save instance id\n"); + goto exit; + } + result = true; + G_LOCK(first_boot_id_file); + remove(FIRST_BOOT_ID_FILE); + G_UNLOCK(first_boot_id_file); } - return; } - if (snapshot) { - *snapshot = false; - } - if (firstboot) { - *firstboot = false; - } +exit: + g_string_free(instance_id, true); + return result; +} - if (stat(LAST_INSTANCE_ID_FILE, &st) != 0) { - LOG(MOD "first boot! - '%s' not found\n", LAST_INSTANCE_ID_FILE); - if (!copy_file(INSTANCE_ID_FILE, LAST_INSTANCE_ID_FILE)) { - LOG(MOD "Copy file failed\n"); +bool is_first_boot(void) { + struct stat st; + bool firstboot = false; + gchar* boot_id; + gchar* first_boot_id; + + G_LOCK(first_boot_id_file); + + if (stat(FIRST_BOOT_ID_FILE, &st) != 0) { + firstboot = true; + if (!copy_file(KERNEL_BOOT_ID_FILE, FIRST_BOOT_ID_FILE)) { + LOG(MOD "Copy file '%s' failed\n", KERNEL_BOOT_ID_FILE); + return false; } - if (firstboot) { - *firstboot = true; + } else { + if (!g_file_get_contents(KERNEL_BOOT_ID_FILE, &boot_id, NULL, NULL)) { + LOG(MOD "Unable to read file '%s'\n", KERNEL_BOOT_ID_FILE); + goto exit; } - cache_firstboot = 1; - cache_snapshot = 0; - return; + if (!g_file_get_contents(FIRST_BOOT_ID_FILE, &first_boot_id, NULL, NULL)) { + LOG(MOD "Unable to read file '%s'\n", FIRST_BOOT_ID_FILE); + g_free(boot_id); + goto exit; + } + if (g_strcmp0(first_boot_id, boot_id) == 0) { + firstboot = true; + } + g_free(first_boot_id); + g_free(boot_id); } - if (!g_file_get_contents(INSTANCE_ID_FILE, &instance_id, NULL, NULL)) { - LOG(MOD "Unable to read file '%s'\n", INSTANCE_ID_FILE); - return; - } - - if (!g_file_get_contents(LAST_INSTANCE_ID_FILE, &last_instance_id, NULL, NULL)) { - LOG(MOD "Unable to read file '%s'\n", LAST_INSTANCE_ID_FILE); - goto fail1; - } - - cache_firstboot = 0; - cache_snapshot = 0; - - if (g_strcmp0(instance_id, last_instance_id) != 0) { - LOG(MOD "first boot!\n"); - if (!copy_file(INSTANCE_ID_FILE, LAST_INSTANCE_ID_FILE)) { - LOG(MOD "Copy file failed\n"); - } - if (snapshot) { - *snapshot = true; - } - if (firstboot) { - *firstboot = true; - } - cache_firstboot = 1; - cache_snapshot = 1; - } - - g_free(last_instance_id); -fail1: - g_free(instance_id); +exit: + G_UNLOCK(first_boot_id_file); + return firstboot; } bool gnode_free(GNode* node, __unused__ gpointer data) { diff --git a/src/lib.h b/src/lib.h index 2156a70..f0e9160 100644 --- a/src/lib.h +++ b/src/lib.h @@ -56,7 +56,7 @@ void LOG(const char *fmt, ...) __attribute__((format(printf, 1, 2))); int make_dir(const char* pathname, mode_t mode) __warn_unused_result__; int chown_path(const char* pathname, const char* ownername, const char* groupname) __warn_unused_result__; bool save_instance_id(const gchar* instance_id) __warn_unused_result__; -void get_boot_info(bool* firstboot, bool* snapshot); +bool is_first_boot(void) __warn_unused_result__; bool write_file(const GString* data, const gchar* file_path, int oflags, mode_t mode) __warn_unused_result__; bool write_sudo_directives(const GString* data, const gchar* filename) __warn_unused_result__; bool write_ssh_keys(const GString* data, const gchar* username) __warn_unused_result__; diff --git a/src/main.c b/src/main.c index 0e03e6a..205a95e 100644 --- a/src/main.c +++ b/src/main.c @@ -135,7 +135,6 @@ int main(int argc, char *argv[]) { bool first_boot_setup = false; bool first_boot = false; bool no_network = false; - bool snapshot = false; char* userdata_filename = NULL; char* tmp_metadata_filename = NULL; char* tmp_data_filesystem = NULL; @@ -215,13 +214,13 @@ int main(int argc, char *argv[]) { fix_disk = true; break; - case OPT_FIRST_BOOT_SETUP: - first_boot_setup = true; - break; + case OPT_FIRST_BOOT_SETUP: + first_boot_setup = true; + break; - case OPT_NO_NETWORK: - no_network = true; - break; + case OPT_NO_NETWORK: + no_network = true; + break; } } @@ -290,7 +289,7 @@ int main(int argc, char *argv[]) { if (!datasource_handler->start()) { result_code = EXIT_FAILURE; } else if(first_boot_setup) { - get_boot_info(&first_boot, &snapshot); + first_boot = is_first_boot(); } break; }