예제 #1
0
int exception_dtable::init(int dfd, const char * file, const params & config, sys_journal * sysj)
{
	const dtable_factory * base_factory;
	const dtable_factory * alt_factory;
	params base_config, alt_config;
	int excp_dfd;
	if(base || alt)
		deinit();
	base_factory = dtable_factory::lookup(config, "base");
	alt_factory = dtable_factory::lookup(config, "alt");
	if(!base_factory || !alt_factory)
		return -EINVAL;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!config.get("alt_config", &alt_config, params()))
		return -EINVAL;
	if(!config.get_blob_or_string("reject_value", &reject_value))
		return -EINVAL;
	/* the reject value must exist, because nonexistent values
	 * can get pruned out if the shadow does not require them */
	if(!reject_value.exists())
		return -EINVAL;
	excp_dfd = openat(dfd, file, O_RDONLY);
	if(excp_dfd < 0)
		return excp_dfd;
	base = base_factory->open(excp_dfd, "base", base_config, sysj);
	if(!base)
		goto fail_base;
	alt = alt_factory->open(excp_dfd, "alt", alt_config, sysj);
	if(!alt)
		goto fail_alt;
	ktype = base->key_type();
	if(ktype != alt->key_type())
		goto fail_ktype;
	cmp_name = base->get_cmp_name();
	
	close(excp_dfd);
	return 0;
	
fail_ktype:
	alt->destroy();
	alt = NULL;
fail_alt:
	base->destroy();
	base = NULL;
fail_base:
	close(excp_dfd);
	return -1;
}
예제 #2
0
int exception_dtable::create(int dfd, const char * file, const params & config, dtable::iter * source, const ktable * shadow)
{
	int excp_dfd, r;
	memory_dtable alt_mdt;
	reject_iter * handler;
	params base_config, alt_config;
	blob reject_value;
	const dtable_factory * base = dtable_factory::lookup(config, "base");
	const dtable_factory * alt = dtable_factory::lookup(config, "alt");
	if(!base || !alt)
		return -EINVAL;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!config.get("alt_config", &alt_config, params()))
		return -EINVAL;
	if(!config.get_blob_or_string("reject_value", &reject_value))
		return -EINVAL;
	/* the reject value must exist, because nonexistent values
	 * can get pruned out if the shadow does not require them */
	if(!reject_value.exists())
		return -EINVAL;
	
	if(!source_shadow_ok(source, shadow))
		return -EINVAL;
	
	r = mkdirat(dfd, file, 0755);
	if(r < 0)
		return r;
	excp_dfd = openat(dfd, file, O_RDONLY);
	if(excp_dfd < 0)
		goto fail_open;
	/* we should really save the reject_value in a meta file here */
	
	/* we'll always be appending, but it's faster if we say false here */
	r = alt_mdt.init(source->key_type(), false, true);
	if(r < 0)
		goto fail_mdt;
	if(source->get_blob_cmp())
		alt_mdt.set_blob_cmp(source->get_blob_cmp());
	
	handler = new reject_iter(source, &alt_mdt, reject_value);
	if(!handler)
		goto fail_mdt;
	
	r = base->create(excp_dfd, "base", base_config, handler, shadow);
	if(r < 0)
		goto fail_base;
	
	/* no shadow - this only has exceptions */
	r = alt->create(excp_dfd, "alt", alt_config, &alt_mdt, NULL);
	if(r < 0)
		goto fail_alt;
	
	delete handler;
	close(excp_dfd);
	return 0;
	
fail_alt:
	util::rm_r(excp_dfd, "base");
fail_base:
	delete handler;
fail_mdt:
	close(excp_dfd);
fail_open:
	unlinkat(dfd, file, AT_REMOVEDIR);
	return -1;
}