/* currently only commit the top level scope */ D_Scope * commit_D_Scope(D_Scope *st) { D_Scope *x = st; if (st->up) return st; while (x->search) x = x->search; commit_ll(st, x->hash); commit_update(st, x->hash); return x; }
static int execute_update_commands(WIMStruct *wim, const struct wimlib_update_command *cmds, size_t num_cmds, int update_flags) { struct wim_inode_table *inode_table; struct wim_sd_set *sd_set; struct list_head unhashed_streams; struct update_command_journal *j; union wimlib_progress_info info; int ret; if (have_command_type(cmds, num_cmds, WIMLIB_UPDATE_OP_ADD)) { /* If we have at least one "add" command, create the inode and * security descriptor tables to index new inodes and new * security descriptors, respectively. */ inode_table = alloca(sizeof(struct wim_inode_table)); sd_set = alloca(sizeof(struct wim_sd_set)); ret = init_inode_table(inode_table, 9001); if (ret) goto out; ret = init_sd_set(sd_set, wim_get_current_security_data(wim)); if (ret) goto out_destroy_inode_table; INIT_LIST_HEAD(&unhashed_streams); } else { inode_table = NULL; sd_set = NULL; } /* Start an in-memory journal to allow rollback if something goes wrong */ j = new_update_command_journal(num_cmds, &wim_get_current_image_metadata(wim)->root_dentry, wim->lookup_table); if (!j) { ret = WIMLIB_ERR_NOMEM; goto out_destroy_sd_set; } info.update.completed_commands = 0; info.update.total_commands = num_cmds; ret = 0; for (size_t i = 0; i < num_cmds; i++) { DEBUG("Executing update command %zu of %zu (op=%"TS")", i + 1, num_cmds, update_op_to_str(cmds[i].op)); info.update.command = &cmds[i]; if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS) { ret = call_progress(wim->progfunc, WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND, &info, wim->progctx); if (ret) goto rollback; } switch (cmds[i].op) { case WIMLIB_UPDATE_OP_ADD: ret = execute_add_command(j, wim, &cmds[i], inode_table, sd_set, &unhashed_streams); break; case WIMLIB_UPDATE_OP_DELETE: ret = execute_delete_command(j, wim, &cmds[i]); break; case WIMLIB_UPDATE_OP_RENAME: ret = execute_rename_command(j, wim, &cmds[i]); break; } if (unlikely(ret)) goto rollback; info.update.completed_commands++; if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS) { ret = call_progress(wim->progfunc, WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND, &info, wim->progctx); if (ret) goto rollback; } next_command(j); } commit_update(j); if (inode_table) { struct wim_image_metadata *imd; imd = wim_get_current_image_metadata(wim); list_splice_tail(&unhashed_streams, &imd->unhashed_streams); inode_table_prepare_inode_list(inode_table, &imd->inode_list); } goto out_destroy_sd_set; rollback: if (sd_set) rollback_new_security_descriptors(sd_set); rollback_update(j); out_destroy_sd_set: if (sd_set) destroy_sd_set(sd_set); out_destroy_inode_table: if (inode_table) destroy_inode_table(inode_table); out: return ret; }
static int sj_init() { struct v7 *v7 = s_v7; LOG(LL_INFO, ("Mongoose IoT Firmware %s", build_id)); LOG(LL_INFO, ("RAM: %d total, %d free", sj_get_heap_size(), sj_get_free_heap_size())); int r = start_nwp(); if (r < 0) { LOG(LL_ERROR, ("Failed to start NWP: %d", r)); return 0; } int boot_cfg_idx = get_active_boot_cfg_idx(); if (boot_cfg_idx < 0) return 0; struct boot_cfg boot_cfg; if (read_boot_cfg(boot_cfg_idx, &boot_cfg) < 0) return 0; LOG(LL_INFO, ("Boot cfg %d: 0x%llx, 0x%u, %s @ 0x%08x, %s", boot_cfg_idx, boot_cfg.seq, boot_cfg.flags, boot_cfg.app_image_file, boot_cfg.app_load_addr, boot_cfg.fs_container_prefix)); uint64_t saved_seq = 0; if (boot_cfg.flags & BOOT_F_FIRST_BOOT) { /* Tombstone the current config. If anything goes wrong between now and * commit, next boot will use the old one. */ saved_seq = boot_cfg.seq; boot_cfg.seq = BOOT_CFG_TOMBSTONE_SEQ; write_boot_cfg(&boot_cfg, boot_cfg_idx); } r = init_fs(boot_cfg.fs_container_prefix); if (r < 0) { LOG(LL_ERROR, ("FS init error: %d", r)); if (boot_cfg.flags & BOOT_F_FIRST_BOOT) { revert_update(boot_cfg_idx, &boot_cfg); } return 0; } if (boot_cfg.flags & BOOT_F_FIRST_BOOT) { LOG(LL_INFO, ("Applying update")); if (apply_update(boot_cfg_idx, &boot_cfg) < 0) { revert_update(boot_cfg_idx, &boot_cfg); } } mongoose_init(); #ifndef CS_DISABLE_JS v7 = s_v7 = init_v7(&v7); /* Disable GC during JS API initialization. */ v7_set_gc_enabled(v7, 0); sj_gpio_api_setup(v7); sj_i2c_api_setup(v7); sj_wifi_api_setup(v7); sj_timers_api_setup(v7); #endif sj_v7_ext_api_setup(v7); sj_init_sys(v7); sj_wifi_init(v7); #ifndef DISABLE_C_CLUBBY sj_clubby_init(); #endif sj_http_api_setup(v7); #if !defined(DISABLE_C_CLUBBY) && !defined(CS_DISABLE_JS) sj_clubby_api_setup(v7); #endif /* Common config infrastructure. Mongoose & v7 must be initialized. */ init_device(v7); sj_updater_post_init(v7); #ifndef DISABLE_C_CLUBBY init_updater_clubby(v7); #endif #ifndef CS_DISABLE_JS /* SJS initialized, enable GC back, and trigger it */ v7_set_gc_enabled(v7, 1); v7_gc(v7, 1); v7_val_t res; if (v7_exec_file(v7, "sys_init.js", &res) != V7_OK) { fprintf(stderr, "Error: "); v7_fprint(stderr, v7, res); } #endif LOG(LL_INFO, ("%s init done, RAM: %d free", "Sys", sj_get_free_heap_size())); if (!sj_app_init(v7)) { LOG(LL_ERROR, ("App init failed")); abort(); } LOG(LL_INFO, ("%s init done, RAM: %d free", "App", sj_get_free_heap_size())); if (boot_cfg.flags & BOOT_F_FIRST_BOOT) { boot_cfg.seq = saved_seq; commit_update(boot_cfg_idx, &boot_cfg); clubby_updater_finish(0); } else { /* * If there is no update reply state, this will just be ignored. * But if there is, then update was rolled back and reply will be sent. */ clubby_updater_finish(-1); } #ifndef CS_DISABLE_JS sj_prompt_init(v7); #endif return 1; }