From dce3337f39ec95d8a56db5220ec8902b03162401 Mon Sep 17 00:00:00 2001 From: Julio Montes Date: Thu, 28 Jan 2016 11:10:52 -0600 Subject: [PATCH] add functions to save instance id and detect vm's first boot save_instance_id must be used by datasources to save instance id is_firstboot uses instance id to detect vm's first boot --- src/lib.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.h | 2 ++ 2 files changed, 54 insertions(+) diff --git a/src/lib.c b/src/lib.c index 6ed2924..007c066 100644 --- a/src/lib.c +++ b/src/lib.c @@ -64,6 +64,8 @@ #define MOD "lib: " #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" void LOG(const char *fmt, ...) { @@ -446,6 +448,56 @@ 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); + 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; +} + +bool is_firstboot(void) { + gchar* instance_id = NULL; + gchar* last_instance_id = NULL; + bool result = false; + struct stat st; + + if (stat(LAST_INSTANCE_ID_FILE, &st) != 0) { + LOG(MOD "first boot!\n"); + if (!copy_file(INSTANCE_ID_FILE, LAST_INSTANCE_ID_FILE)) { + LOG(MOD "Copy file failed\n"); + } + return true; + } + + if (!g_file_get_contents(INSTANCE_ID_FILE, &instance_id, NULL, NULL)) { + LOG(MOD "Unable to read file '%s'\n", INSTANCE_ID_FILE); + return false; + } + + 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; + } + + if (g_strcmp0(instance_id, last_instance_id) != 0) { + result = true; + LOG(MOD "first boot!\n"); + if (!copy_file(INSTANCE_ID_FILE, LAST_INSTANCE_ID_FILE)) { + LOG(MOD "Copy file failed\n"); + } + } + + g_free(last_instance_id); +fail1: + g_free(instance_id); + return result; +} + bool gnode_free(GNode* node, __unused__ gpointer data) { if (node->data) { g_free(node->data); diff --git a/src/lib.h b/src/lib.h index 51c7fdf..140658c 100644 --- a/src/lib.h +++ b/src/lib.h @@ -56,6 +56,8 @@ bool exec_task_async(const gchar* command_line, GChildWatchFunc async_func_watch 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__; +bool is_firstboot(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__;