Exemple #1
0
/* 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;
}
Exemple #2
0
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;
}