static int
init_static_vars(int argc, char ** args)
{
	GError *err;
	
	if (argc<4) {
		g_printerr("Failed to init the address and container_id : 4 tokens expected (IP, PORT, CONTAINER_ID, SERVICE_NAME)\r\n");
		abort();
	}

	err = NULL;
	if (!metacnx_init(&cnx, args[0], atoi(args[1]), &err)) {
		g_printerr("Failed to init address : %s\r\n", gerror_get_message(err));
		abort();
	}
	cnx.timeout.req = cnx.timeout.cnx = 5000;

	if (!container_id_hex2bin(args[2],strlen(args[2]),&cid,&err)) {
		g_printerr("Failed to read the container_id : %s\r\n", gerror_get_message(err));
		abort();
	} else {
		gchar str_cid[STRLEN_CONTAINERID];
		container_id_to_string(cid,str_cid,sizeof(str_cid));
		g_printerr("Using container [%s]\n", str_cid);
	}

	g_strlcpy(service_name,args[3],sizeof(service_name));

	return 4;
}
static void
allservice_check_start_HT(struct namespace_data_s *ns_data, GHashTable *ht)
{
	gsize offset;
	struct taskdata_checksrv_s td_scheme;
	GHashTableIter iter_serv;
	gpointer k, v;

	TRACE_POSITION();

	g_hash_table_iter_init(&iter_serv, ht);
	while (g_hash_table_iter_next(&iter_serv, &k, &v)) {
		struct service_info_s *si = v;

		memset(&td_scheme, 0x00, sizeof(td_scheme));
		offset = g_snprintf(td_scheme.task_name, sizeof(td_scheme.task_name), "%s.", TASK_ID);
		addr_info_to_string(&(si->addr), td_scheme.task_name+offset, sizeof(td_scheme.task_name)-offset);
		g_strlcpy(td_scheme.ns_name, ns_data->name, sizeof(td_scheme.ns_name)-1);

		if (!_agent_check_enabled(si)) {
			GRID_DEBUG("Task [%s] disabled by "
					NAME_TAGNAME_AGENT_CHECK, td_scheme.task_name);
		} else if (!is_task_scheduled(td_scheme.task_name)) {
			GError *error_local = NULL;
			task_t *task = NULL;
			struct taskdata_checksrv_s *task_data;

			TRACE_POSITION();

			agent_get_service_key(si, td_scheme.srv_key, sizeof(td_scheme.srv_key));
			g_strlcpy(td_scheme.srv_key, (gchar*)k, sizeof(td_scheme.srv_key)-1);

			/* prepare the task structure */
			task_data = g_memdup(&td_scheme, sizeof(td_scheme));
			if (!task_data) {
				ERROR("Memory allocation failure");
				continue;
			}

			task = create_task(period_check_services, td_scheme.task_name);
			task = set_task_callbacks(task, _check_tcp_service_task,
					g_free, task_data);
			if (!task) {
				ERROR("Memory allocation failure");
				continue;
			}

			/* now start the task! */
			if (add_task_to_schedule(task, &error_local))
				INFO("Task started: %s", td_scheme.task_name);
			else {
				ERROR("Failed to add task to scheduler [%s] : %s", td_scheme.task_name, gerror_get_message(error_local));
				g_free(task);
			}
			if (error_local)
				g_clear_error(&error_local);
		}
	}
	TRACE_POSITION();
}
Example #3
0
static void
monitoring_loop(service_info_t *si)
{
	long jiffies = 0;
	GTimer *timer;
	GError *error = NULL;
	guint proc_count;

	timer = g_timer_new();
	monitor_get_status(svc_mon, si);
	_add_custom_tags(si);

	proc_count = supervisor_children_startall(NULL, NULL);
	DEBUG("First started %u processes", proc_count);

	for (;;) { /* main loop */
		struct timeval tv_sleep;

		if (flag_restart_children) {
			if (auto_restart_children) {
				supervisor_children_repair(CHILD_KEY);
				supervisor_children_enable(CHILD_KEY, TRUE);
				proc_count = supervisor_children_startall(NULL,NULL);

				DEBUG("Started %u processes", proc_count);
				flag_restart_children = !!proc_count;
			} else {
				DEBUG("One of my children died, I will die too (auto_restart_children=%d)", auto_restart_children);
				break;
			}
		}

		if (!flag_running)
			break;

		if (g_timer_elapsed(timer, NULL) >= 1.0) {
			if (!((++jiffies) % monitor_period)) {
				monitor_get_status(svc_mon, si);
				_add_custom_tags(si);
			}
			if (!register_namespace_service(si, &error)) {
				ERROR("Failed to register the service: %s", gerror_get_message(error));
				g_clear_error(&error);
			}
			g_timer_reset(timer);
		}

		tv_sleep.tv_sec = 1L;
		tv_sleep.tv_usec = 0L;
		select(0, NULL, NULL, NULL, &tv_sleep);
		errno = 0;
	}

	supervisor_children_stopall(4);
	supervisor_children_catharsis(NULL, NULL);

	g_free(timer);
}
Example #4
0
static void
monitoring_loop(service_info_t *si)
{
	long jiffies = 0;
	GTimer *timer;
	GError *error = NULL;
	guint proc_count;

	timer = g_timer_new();
	monitor_get_status(svc_mon, si);
	_add_custom_tags(si);

	proc_count = supervisor_children_startall(NULL, NULL);
	GRID_DEBUG("First started %u processes", proc_count);

	while (flag_running) { /* main loop */

		if (flag_restart_children) {
			if (auto_restart_children) {
				supervisor_children_repair(CHILD_KEY);
				supervisor_children_enable(CHILD_KEY, TRUE);
				proc_count = supervisor_children_startall(NULL,NULL);

				GRID_DEBUG("Started %u processes", proc_count);
				flag_restart_children = !!proc_count;
			} else {
				GRID_DEBUG("One of my children died, I will die too (auto_restart_children=%d)", auto_restart_children);
				break;
			}
		}

		if (!flag_running)
			break;

		gdouble elapsed = g_timer_elapsed(timer, NULL);
		if (elapsed >= 1.0) {
			if (!((++jiffies) % monitor_period)) {
				monitor_get_status(svc_mon, si);
				_add_custom_tags(si);
			}
			if (!register_namespace_service(si, &error)) {
				GRID_WARN("Failed to register the service: %s", gerror_get_message(error));
				g_clear_error(&error);
			}
			g_timer_reset(timer);
			elapsed = 0.0;
		}

		g_usleep (1000000UL - ((gulong)elapsed));
	}

	supervisor_children_stopall(4);
	supervisor_children_catharsis(NULL, NULL);

	g_free(timer);
}
static int
test_flush(void)
{
	GError *error_local;
	GSList *services_used, *remaining_services;
	
	error_local = NULL;
	if (!meta2_remote_container_open(&(cnx.addr), cnx.timeout.req, &error_local, cid)) {
		g_printerr("Failed to open the distant container : %s\r\n", gerror_get_message(error_local));
		g_clear_error(&error_local);
		return 0;
	}

	services_used = NULL;
	if (!meta2_remote_service_flush(&cnx, cid, service_name, &services_used, &error_local)) {
		g_printerr("Container flush failed for service type [%s] : %s\r\n",
			service_name, gerror_get_message(error_local));
		g_clear_error(&error_local);
		return 0;
	}

	remaining_services = meta2_remote_service_get_all_used(&cnx, cid, service_name, &error_local);
	if (error_local) {
		_gfree_list(&services_used);
		g_printerr("Failed to list the services of type [%s] : %s\r\n",
			service_name, gerror_get_message(error_local));
		g_clear_error(&error_local);
		return 0;
	}
	if (remaining_services) {
		g_printerr("Bad container flsh, some services remain [%d]\r\n", g_slist_length(remaining_services));
		_gfree_list(&remaining_services);
		_gfree_list(&services_used);
		return 0;
	}
	
	return 1;
}
Example #6
0
static enum scanner_traversal_e
check_chunk_and_sleep(const char *chunk_path, void *data)
{
	GError *local_error = NULL;
	struct chunk_checker_data_s *cc_data;

	cc_data = data;

	if (!check_chunk(chunk_path, cc_data->volume_path, &local_error)) {
		ERROR("check_chunk(%s) : %s", chunk_path, gerror_get_message(local_error));
		g_clear_error(&local_error);
	}

	sleep(cc_data->sleep_time);

	return SCAN_CONTINUE;
}
Example #7
0
static void
exec_scheduled_tasks(task_t *task)
{
	int rc;
	GError *error;

	error = NULL;
	if (!task->task_handler)
		return;
	rc = task->task_handler(task->udata, &error);
	if (!rc) {
		ERROR("Failed to execute task=[%s]: %s", task->id, gerror_get_message(error));
		task->busy = FALSE;
	}
	if (error)
		g_clear_error(&error);
}
Example #8
0
static void
allservice_check_start_HT(struct namespace_data_s *ns_data, GHashTable *ht)
{
	gsize offset;
	struct taskdata_checksrv_s td_scheme;
	GHashTableIter iter_serv;
	gpointer k, v;


	g_hash_table_iter_init(&iter_serv, ht);
	while (g_hash_table_iter_next(&iter_serv, &k, &v)) {
		struct service_info_s *si = v;
		gboolean srv_check_enabled = TRUE;

		/* Services can disable TCP checks (enabled by default) */
		service_tag_t *tag = service_info_get_tag(si->tags,
				NAME_TAGNAME_AGENT_CHECK);
		if (tag) {
			GError *err = NULL;
			if (tag->type == STVT_BOOL) {
				service_tag_get_value_boolean(tag, &srv_check_enabled, &err);
			} else {
				gchar buf[64] = {0};
				service_tag_get_value_string(tag, buf, sizeof(buf), &err);
				srv_check_enabled = metautils_cfg_get_bool(buf, TRUE);
			}
			g_clear_error(&err);
		}

		memset(&td_scheme, 0x00, sizeof(td_scheme));
		offset = g_snprintf(td_scheme.task_name, sizeof(td_scheme.task_name), "%s.", TASK_ID);
		addr_info_to_string(&(si->addr), td_scheme.task_name+offset, sizeof(td_scheme.task_name)-offset);
		g_strlcpy(td_scheme.ns_name, ns_data->name, sizeof(td_scheme.ns_name)-1);

		if (!srv_check_enabled) {
			GRID_DEBUG("Task [%s] disabled by "
					NAME_TAGNAME_AGENT_CHECK, td_scheme.task_name);
		} else if (!is_task_scheduled(td_scheme.task_name)) {
			GError *error_local = NULL;
			task_t *task = NULL;
			struct taskdata_checksrv_s *task_data;


			agent_get_service_key(si, td_scheme.srv_key, sizeof(td_scheme.srv_key));
			g_strlcpy(td_scheme.srv_key, (gchar*)k, sizeof(td_scheme.srv_key)-1);

			/* prepare the task structure */
			task_data = g_memdup(&td_scheme, sizeof(td_scheme));
			if (!task_data) {
				ERROR("Memory allocation failure");
				continue;
			}

			task = create_task(period_check_services, td_scheme.task_name);
			task = set_task_callbacks(task, _check_tcp_service_task,
					g_free, task_data);
			if (!task) {
				ERROR("Memory allocation failure");
				continue;
			}
			
			/* now start the task! */
			if (add_task_to_schedule(task, &error_local))
				INFO("Task started: %s", td_scheme.task_name);
			else {
				ERROR("Failed to add task to scheduler [%s] : %s", td_scheme.task_name, gerror_get_message(error_local));
				g_free(task);
			}
			if (error_local)
				g_clear_error(&error_local);
		}
	}
}
Example #9
0
int
main_http_config(const gchar *hn, int fd)
{
	int rc;
	GError *error = NULL;
	GByteArray *gba_services = NULL;
	GByteArray *gba_files = NULL;
	ne_session *http_session;

	set_sighandlers();
	fd_out = fd;

	DEBUG("Starting a new configuration process");
	rc = -1;

	bzero(hostname, sizeof(hostname));
	if (!hn)
		gethostname(hostname,sizeof(hostname));
	else
		g_strlcpy(hostname, hn, sizeof(hostname)-1);

	http_session = ne_session_create("http", gridconf_host, gridconf_port);
	ne_set_connect_timeout(http_session, 1);
	ne_set_read_timeout(http_session, 4);

	/*downlaod each file*/
	if (!is_running)
		goto label_error;

	gba_files = download_file_list(http_session, &error);
	if (!gba_files) {
		ERROR("Failed to get the files list file : %s", gerror_get_message(error));
		goto label_error;
	}
	
	if (!is_running)
		goto label_error;
	
	gba_services = download_file_services(http_session, &error);
	if (!gba_services) {
		ERROR("Failed to get the services definition file : %s", gerror_get_message(error));
		goto label_error;
	}
	
	if (!is_running)
		goto label_error;
	
	if (!download_each_configuration_file(http_session, gba_files, &error)) {
		ERROR("Failed to download a configuration file : %s", gerror_get_message(error));
		goto label_error;
	}

	if (!is_running)
		goto label_error;

	if (!dump_gba(gba_services, fd_out, &error)) {
		ERROR("Failed to dump the configuration to fd=%d : %s", fd_out, gerror_get_message(error));
		goto label_error;
	}

	rc = 0;
label_error:
	ne_session_destroy(http_session);
	metautils_pclose(&fd_out);
	if (gba_services)
		g_byte_array_free(gba_services, TRUE);
	if (gba_files)
		g_byte_array_free(gba_files, TRUE);
	DEBUG("http_config child pid=%d exiting with rc=%d", getpid(), rc);
	return rc;
}
Example #10
0
apr_status_t
chunk_bucket_read(apr_bucket *b, const char **str, apr_size_t *len, apr_read_type_e block)
{
	apr_size_t written=0, length=0;
	apr_size_t offset = 0;
	apr_int64_t total64, remaining64, done64;
	apr_int64_t bl64, w64;
	ssize_t w;
	dav_resource_private *ctx;
	apr_status_t rc;
	rc = APR_SUCCESS;

	(void) block;

	*str = NULL;  /* in case we die prematurely */
	*len = 0;

	/*dummy bucket*/
	if (b->length == (apr_size_t)(-1) || b->start == (apr_off_t)(-1))
		return APR_SUCCESS;
	
	ctx = b->data;
	offset = b->start - ctx->cp_chunk.read;
	DAV_DEBUG_REQ(ctx->request, 0, "Reading data for this bucket start at current position + %"APR_SIZE_T_FMT, offset);
	DAV_DEBUG_REQ(ctx->request, 0, "Bucket length %"APR_SIZE_T_FMT, b->length);
	total64 = g_ascii_strtoll(ctx->cp_chunk.uncompressed_size, NULL, 10);
	done64 = b->start;
	bl64 = b->length;
	remaining64 = MIN(total64 - done64, bl64);

	DAV_DEBUG_REQ(ctx->request, 0, "Data already returned=%"APR_INT64_T_FMT", remaining=%"APR_INT64_T_FMT, done64, remaining64);

	if (remaining64 <= 0){
		DAV_DEBUG_REQ(ctx->request, 0, "No remaining data, end of resource delivering.");
		apr_bucket_heap_make(b, NULL, *len, apr_bucket_free);
		return APR_SUCCESS;
	}
	else { /* determine the size of THIS bucket */
		if (remaining64 > APR_BUCKET_BUFF_SIZE)
			length = APR_BUCKET_BUFF_SIZE;
		else
			length = remaining64;
	}

	*len = length;

	guint8 *buf = apr_bucket_alloc(length, b->list);
	for (written=0; written < length ;) {
		GError *gerror;
	
		DAV_DEBUG_REQ(ctx->request, 0, "Trying to read at most %"APR_SSIZE_T_FMT" bytes (%"APR_SSIZE_T_FMT" received)",
				length - written, written);
		
		gerror = NULL;
		w = ctx->comp_ctx.data_uncompressor(&ctx->cp_chunk, offset, buf+written, length-written, &gerror);
		offset = 0;
		DAV_DEBUG_REQ(ctx->request, 0 , "%"APR_SSIZE_T_FMT" bytes read from local resource", w);
		if (w < 0) {
			DAV_ERROR_REQ(ctx->request, 0, "Read from chunk failed : %s", gerror_get_message(gerror));
			if (gerror)
				g_error_free(gerror);
			apr_bucket_free(buf);
			return APR_INCOMPLETE;
		}
		if (gerror)
			g_error_free(gerror);
		if (w == 0) {
			DAV_DEBUG_REQ(ctx->request, 0, "No bytes read from local resource whereas we"
						" must read again, this should never happened");
			apr_bucket_free(buf);
			return APR_INCOMPLETE;
		}
		written += w;
	}
	*len = written;

	DAV_DEBUG_REQ(ctx->request, 0, "Bucket done (%"APR_SSIZE_T_FMT" bytes, rc=%d)", written, rc);

	w64 = written;

	DAV_DEBUG_REQ(ctx->request, 0, "Status info : %"APR_INT64_T_FMT" written , %"APR_INT64_T_FMT" length total", w64, bl64);

	apr_bucket_heap_make(b, (char*)buf, *len, apr_bucket_free);

	if(w64 < bl64) {
		apr_bucket *bkt;
		DAV_DEBUG_REQ(ctx->request, 0, "Creating bucket info: bkt->length = %"APR_INT64_T_FMT", bkt->start ="
					" %"APR_INT64_T_FMT", bkt->data = %p, bkt->list = %p\n", remaining64, done64 + w64,
					&(ctx->cp_chunk), b->list);
		bkt = apr_bucket_alloc(sizeof(*bkt), b->list);
		bkt->type = &chunk_bucket_type;
		bkt->length = remaining64 - w64;
		bkt->start = done64 + w64;
		bkt->data = ctx;
		bkt->free = chunk_bucket_free_noop;
		bkt->list = b->list;
		APR_BUCKET_INSERT_AFTER(b, bkt);
		DAV_DEBUG_REQ(ctx->request, 0, "Starting a new RAWX bucket (length=%"APR_SIZE_T_FMT" start=%"APR_INT64_T_FMT")", bkt->length, bkt->start);
	}

	*str = (char*)buf;
	return rc;
}
static gboolean
manage_service(struct service_info_s *si)
{
	GError *error_local;
	struct service_info_s *old_si = NULL;
	struct service_tag_s *tag_first = NULL;
	struct namespace_data_s *ns_data;
	gsize key_size;
	gchar key[LIMIT_LENGTH_SRVTYPE + STRLEN_ADDRINFO], str_addr[STRLEN_ADDRINFO];


	if (!si) {
		ERROR("Invalid parameter");
		return FALSE;
	}

	key_size = agent_get_service_key(si, key, sizeof(key));
	grid_addrinfo_to_string(&(si->addr), str_addr, sizeof(str_addr));

	/*this service must refer to known namespace and service type*/
	error_local = NULL;
	if (!(ns_data = get_namespace(si->ns_name, &error_local))) {
		ERROR("Namespace unavailable for service [ns=%s type=%s addr=%s] : %s",
			si->ns_name, si->type, str_addr, gerror_get_message(error_local));
		if (error_local)
			g_error_free(error_local);
		return FALSE;
	}

	/*Info trace when a service of a new type is used */
	if (error_local)
		g_error_free(error_local);
	if (!conscience_get_srvtype(ns_data->conscience, &error_local, si->type, MODE_STRICT)) {
		/*to avoid traces flooding, if the service already exists, no trace is sent */
		if (!g_hash_table_lookup(ns_data->local_services, key)
				&& !g_hash_table_lookup(ns_data->down_services, key)) {
			INFO("New service type discovered [ns=%s type=%s addr=%s]", ns_data->name, si->type, str_addr);
		}
	}

	/*replace MACRO tags by their true values */
	if (error_local)
		g_clear_error(&error_local);

	metautils_srvinfo_ensure_tags (si);

	si->score.value = SCORE_UNSET;
	si->score.timestamp = oio_ext_real_time() / G_TIME_SPAN_SECOND;

	/*then keep the score */
	g_hash_table_remove(ns_data->down_services, key);

	/* save first lauched tag if still in old si */
	old_si = g_hash_table_lookup(ns_data->local_services, key);
	if (old_si != NULL) {
		tag_first = service_info_get_tag(old_si->tags, NAME_TAGNAME_RAWX_FIRST);
		if (tag_first != NULL)
			service_tag_set_value_boolean(service_info_ensure_tag(si->tags, NAME_TAGNAME_RAWX_FIRST), tag_first->value.b);
	}

	service_tag_set_value_boolean(service_info_ensure_tag(si->tags, "tag.up"), TRUE);
	g_hash_table_insert(ns_data->local_services, g_strndup(key, key_size), si);

	DEBUG("Service registration [ns=%s type=%s addr=%s]", ns_data->name, si->type, str_addr);

	if (error_local)
		g_error_free(error_local);
	return TRUE;
}
Example #12
0
static int
rawx_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp,
		server_rec *server)
{
	apr_status_t status;
	enum lock_state_e state;
	server_rec *s;
	server_addr_rec *a;
	dav_rawx_server_conf *conf;
	GError *gerr;
	int volume_validated = 0;

	(void) ptemp;
	DAV_XDEBUG_POOL(plog, 0, "%s(%lx)", __FUNCTION__, (long)server);

	if (__rawx_is_first_call(server)) {
		DAV_DEBUG_POOL(plog, 0, "First call detected");
		return OK;
	}

	DAV_DEBUG_POOL(plog, 0, "Second call detected");

	gerr = NULL;
	conf = ap_get_module_config(server->module_config, &dav_rawx_module);

	DAV_XDEBUG_POOL(plog, 0, "Checking the docroot XATTR lock for [%s]",
			conf->docroot);

	/* Runs the configured servers and check they do not serve
	 * the grid docroot with an unauthorized IP:PORT couple */
	for (s = server ; s ; s = s->next) {

		for (a = s->addrs ; a ; a = a->next) {
			apr_status_t status2;
			char *host = NULL, url[512];

			if (gerr)
				g_clear_error(&gerr);
			if (a->host_port == 0)
				continue;

			host = NULL;
			status2 = apr_getnameinfo(&host, a->host_addr,
					NI_NUMERICSERV|NI_NUMERICHOST|NI_NOFQDN);
			if (status2 != APR_SUCCESS || host == NULL) {
				DAV_ERROR_POOL(plog, 0, "getnameinfo() failed : %d", status2);
				continue;
			}

			apr_snprintf(url, sizeof(url), "%s:%d", host, a->host_port);
			DAV_DEBUG_POOL(plog, 0, "xattr-lock : testing addr [%s]", url);

			state = rawx_get_volume_lock_state(conf->docroot, conf->ns_name,
					url, &gerr);
			switch (state) {

				case ERROR_LS:
					DAV_ERROR_POOL(plog, 0, "Failed to check the docroot ownership: %s",
							gerror_get_message(gerr));
					goto label_error;

				case NOLOCK_LS:
					if (!rawx_lock_volume(conf->docroot, conf->ns_name, url, 0, &gerr)) {
						DAV_ERROR_POOL(plog, 0, "Failed to grab the docroot ownership: %s",
								gerror_get_message(gerr));
						goto label_error;
					}
					DAV_DEBUG_POOL(plog, 0, "Docroot now owned");
					volume_validated = ~0;
					break;

				case OWN_LS:
					DAV_DEBUG_POOL(plog, 0, "Docroot already owned by the current server");
					if (!rawx_lock_volume(conf->docroot, conf->ns_name, url,
							RAWXLOCK_FLAG_OVERWRITE, &gerr))
						DAV_ERROR_POOL(plog, 0, "Failed to complete the docroot ownership: %s",
							gerror_get_message(gerr));
					volume_validated = ~0;
					break;

				case OTHER_LS:
					DAV_ERROR_POOL(plog, 0, "Another RAWX already used the docroot (see XATTR)"
							" : %s", gerror_get_message(gerr));
					goto label_error;
			}
		}
	}

	if (gerr)
		g_clear_error(&gerr);

	if (!volume_validated) {
		DAV_ERROR_POOL(plog, 0, "No server found, could not validate the RAWX volume. "
			"Did you declare at least one VirtualHost ?");
		goto label_error;
	}

	if (_create_shm_if_needed(conf->shm.path, server, plog) != APR_SUCCESS) {
		DAV_ERROR_POOL(plog, 0, "Failed to init the RAWX statistics support");
		return DONE;
	}

	/* Init the stat support : doing this so late avoids letting orphan
	 * SHM segments in the nature in case of previous errors */
	status = server_init_master_stat(conf, pconf, plog);
	if (APR_SUCCESS != status) {
		DAV_ERROR_POOL(plog, 0, "Failed to init the RAWX statistics support");
		return DONE;
	}
	else {
		/* This will be overwritten by the child_init */
		conf->cleanup = _stat_cleanup_master;
		apr_pool_userdata_set(conf, apr_psprintf(pconf,
				"RAWX-config-to-be-cleaned-%d", i++),
				_stat_cleanup_to_register, pconf);
	}

	return OK;

label_error:
	if (gerr)
		g_clear_error(&gerr);
	return DONE;
}
static dav_error *
dav_rawx_deliver(const dav_resource *resource, ap_filter_t *output)
{
	dav_rawx_server_conf *conf;
	apr_pool_t *pool;
	apr_bucket_brigade *bb = NULL;
	apr_status_t status;
	apr_bucket *bkt = NULL;
	dav_resource_private *ctx;
	dav_error *e = NULL;

	apr_finfo_t info;

	DAV_XDEBUG_RES(resource, 0, "%s(%s)", __FUNCTION__, resource_get_pathname(resource));

	pool = resource->pool;
	conf = resource_get_server_config(resource);

	/* Check resource type */
	if (DAV_RESOURCE_TYPE_REGULAR != resource->type) {
		e = server_create_and_stat_error(conf, pool, HTTP_CONFLICT, 0, "Cannot GET this type of resource.");
		goto end_deliver;
	}

	if (resource->collection) {
		e = server_create_and_stat_error(conf, pool, HTTP_CONFLICT, 0, "No GET on collections");
		goto end_deliver;
	}

	ctx = resource->info;

	if (ctx->update_only) {
		/* Check if it is not a busy file. We accept reads during
		 * compression but not attr updates. */
		char *pending_file = apr_pstrcat(pool,
				resource_get_pathname(resource), ".pending", NULL);
		status = apr_stat(&info, pending_file, APR_FINFO_ATIME, pool);
		if (status == APR_SUCCESS) {
			e = server_create_and_stat_error(conf, pool, HTTP_FORBIDDEN,
					0, "File in pending mode.");
			goto end_deliver;
		}

		GError *error_local = NULL;
		/* UPDATE chunk attributes and go on */
		const char *path = resource_get_pathname(resource);
		FILE *f = NULL;
		f = fopen(path, "r");
		/* Try to open the file but forbids a creation */
		if (!set_rawx_info_to_fd(fileno(f), &error_local, &(ctx->chunk))) {
			fclose(f);
			e = server_create_and_stat_error(conf, pool,
					HTTP_FORBIDDEN, 0, apr_pstrdup(pool, gerror_get_message(error_local)));
			g_clear_error(&error_local);
			goto end_deliver;
		}
		fclose(f);
	} else {
		bb = apr_brigade_create(pool, output->c->bucket_alloc);

		if (!ctx->compression){
			apr_file_t *fd = NULL;

			/* Try to open the file but forbids a creation */
			status = apr_file_open(&fd, resource_get_pathname(resource),
					APR_READ|APR_BINARY|APR_BUFFERED, 0, pool);
			if (APR_SUCCESS != status) {
				e = server_create_and_stat_error(conf, pool, HTTP_FORBIDDEN,
						0, "File permissions deny server access.");
				goto end_deliver;
			}

			/* FIXME this does not handle large files. but this is test code anyway */
			bkt = apr_bucket_file_create(fd, 0,
					(apr_size_t)resource->info->finfo.size,
					pool, output->c->bucket_alloc);
		}
		else {
			DAV_DEBUG_RES(resource, 0, "Building a compressed resource bucket");
			gint i64;

			i64 = g_ascii_strtoll(ctx->cp_chunk.uncompressed_size, NULL, 10);

			/* creation of compression specific bucket */
			bkt = apr_pcalloc(pool, sizeof(struct apr_bucket));
			bkt->type = &chunk_bucket_type;
			bkt->length = i64;
			bkt->start = 0;
			bkt->data = ctx;
			bkt->free = chunk_bucket_free_noop;
			bkt->list = output->c->bucket_alloc;
		}

		APR_BRIGADE_INSERT_TAIL(bb, bkt);

		/* as soon as the chunk has been sent, end of stream!*/
		bkt = apr_bucket_eos_create(output->c->bucket_alloc);
		APR_BRIGADE_INSERT_TAIL(bb, bkt);

		if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS){
			e = server_create_and_stat_error(conf, pool, HTTP_FORBIDDEN, 0, "Could not write contents to filter.");
			/* close file */
			if (ctx->cp_chunk.fd) {
				fclose(ctx->cp_chunk.fd);
			}
			goto end_deliver;
		}
		if (ctx->cp_chunk.buf){
			g_free(ctx->cp_chunk.buf);
			ctx->cp_chunk.buf = NULL;
		}
		if (ctx->cp_chunk.uncompressed_size){
			g_free(ctx->cp_chunk.uncompressed_size);
			ctx->cp_chunk.uncompressed_size = NULL;
		}

		/* close file */
		if (ctx->cp_chunk.fd) {
			fclose(ctx->cp_chunk.fd);
		}

		server_inc_stat(conf, RAWX_STATNAME_REP_2XX, 0);
		server_add_stat(conf, RAWX_STATNAME_REP_BWRITTEN, resource->info->finfo.size, 0);
	}

end_deliver:

	if (bb) {
		apr_brigade_destroy(bb);
		bb = NULL;
	}

	/* Now we pass here even if an error occured, for process request duration */
	server_inc_request_stat(resource_get_server_config(resource), RAWX_STATNAME_REQ_CHUNKGET,
			request_get_duration(resource->info->request));

	return e;
}
Example #14
0
// TODO: convert this to use metautils' common_main
int
main(int argc, char ** argv)
{
	int rc = 1;
	service_info_t *service = NULL;
	setenv("GS_DEBUG_ENABLE", "0", TRUE);

	supervisor_children_init();

	do {
		GError *err = NULL;
		regex_tag = g_regex_new("((stat|tag)\\.([^.=\\s]+))\\s*=\\s*(.*)",
				G_REGEX_CASELESS|G_REGEX_EXTENDED, 0, &err);
		if (!regex_tag) {
			FATAL("Cannot compile tag regex: %s", err->message);
			g_clear_error(&err);
			exit(-1);
		}
		regex_svc = g_regex_new("([^|]*)\\|([^|]*)\\|(.*)",
				G_REGEX_CASELESS, 0, &err);
		if (!regex_svc) {
			FATAL("Cannot compile svc regex: %s", err->message);
			g_clear_error(&err);
			exit(-1);
		}
	} while (0);

	static struct option long_options[] = {
		{"svc-id", 1, 0, 'i'},
		{"monitor", 1, 0, 'm'},
		{"svc-cmd", 1, 0, 'c'},
		{"syslog-id", 1, 0, 's'},
		{"auto-restart-children", 0, 0, 'a'},
		{"monitor-period", 1, 0, 'p'},
		{"no-tcp-check", 0, 0, 'n'},
		{"tag", 1, 0, 't'},
		{0, 0, 0, 0}
	};

	int c;
	int option_index = 0;
	gchar *optarg2 = NULL;
	gchar **kv = NULL;
	while (-1 != (c = getopt_long(argc, argv, "ac:i:m:np:s:t:",
			long_options, &option_index))) {
		switch (c) {
		case 'i':
			g_strlcpy(svc_id, optarg, sizeof(svc_id)-1);
			break;
		case 'm':
			g_strlcpy(svc_mon, optarg, sizeof(svc_mon)-1);
			break;
		case 'c':
			g_strlcpy(svc_cmd, optarg, sizeof(svc_cmd)-1);
			break;
		case 'n':
			kv = g_malloc0(3 * sizeof(gchar*));
			kv[0] = g_strdup("tag.agent_check");
			kv[1] = g_strdup("false");
			custom_tags = g_slist_prepend(custom_tags, kv);
			break;
		case 'a':
			auto_restart_children = TRUE;
			break;
		case 'p':
			monitor_period = strtoll(optarg, NULL, 10);
			break;
		case 's':
			g_strlcpy(syslog_id, optarg, sizeof(syslog_id)-1);
			break;
		case 't':
			if (!g_str_has_prefix(optarg, "tag."))
				optarg2 = g_strdup_printf("tag.%s", optarg);
			else
				optarg2 = g_strdup(optarg);
			kv = g_strsplit(optarg2, "=", 2);
			if (kv && g_strv_length(kv) == 2) {
				custom_tags = g_slist_prepend(custom_tags, kv);
			} else {
				g_printerr("Invalid tag, must contain '=': %s", optarg);
				g_strfreev(kv);
				kv = NULL;
			}
			g_free(optarg2);
			optarg2 = NULL;
			break;
		default:
			g_printerr("Unexpected option: %c\n", c);
			break;
		}
		option_index = 0;
	}

	if (argc <= 1 || strlen(svc_id) == 0 || strlen(svc_cmd) == 0) {
		g_printerr("Usage: %s\n", argv[0]);
		g_printerr("Mandatory options:\n");
		g_printerr("\t-i\t--svc-id <NS|type|ip:port>\n"
				"\t-c\t--svc-cmd </service/cmd/to/launch>\n\n"
				"Other options:\n"
				"\t-m\t--monitor </script/to/monitor>\n"
				"\t-p\t--monitor-period <seconds>\n"
				"\t-s\t--syslog-id <syslog-id>\n"
				"\t-t\t--tag <key=val>\n"
				"\t-a\t--auto-restart-children\n"
				"\t-n\t--no-tcp-check\n");
		return 1;
	}

	if (*syslog_id) {
		logger_init_level(GRID_LOGLVL_INFO);
		logger_syslog_open();
		g_log_set_default_handler(logger_syslog, NULL);
	}

	GError *error = NULL;
	if (!supervisor_children_register(CHILD_KEY, svc_cmd, &error)) {
		g_printerr("Child registration failure:\n\t%s\n", gerror_get_message(error));
		goto label_error;
	}

	if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_THREAD_STACK, 8192 * 1024))
		WARN("Limit on thread stack size cannot be set: %s", strerror(errno));
	if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_MAX_FILES, 32 * 1024))
		WARN("Limit on max opened files cannot be set: %s", strerror(errno));
	if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_CORE_SIZE, -1))
		WARN("Limit on core file size cannot be set: %s", strerror(errno));

	supervisor_children_set_respawn(CHILD_KEY, FALSE);
	supervisor_children_set_working_directory(CHILD_KEY, "/tmp");
	supervisor_preserve_env(CHILD_KEY);

	service = g_malloc0(sizeof(service_info_t));
	if (0 != init_srvinfo(svc_id, service)) {
		g_printerr("Internal error: failed to init srvinfo\n");
		goto label_error;
	}

	freopen("/dev/null", "r", stdin);

	NOTICE("%s restarted, pid=%d", argv[0], getpid());

	signal(SIGQUIT, sighandler_supervisor);
	signal(SIGTERM, sighandler_supervisor);
	signal(SIGINT,  sighandler_supervisor);
	signal(SIGPIPE, sighandler_supervisor);
	signal(SIGUSR1, sighandler_supervisor);
	signal(SIGUSR2, sighandler_supervisor);
	signal(SIGCHLD, sighandler_supervisor);

	monitoring_loop(service);

	rc = 0;

label_error:
	g_slist_free_full(custom_tags, (GDestroyNotify) g_strfreev);
	service_info_clean(service);
	supervisor_children_cleanall();
	return rc;
}
static int
test_add_service(int argc, char ** args, int validation)
{
	GSList *really_removed=NULL, *commit_failed=NULL, *services_used=NULL;
	struct service_info_s *si;
	GSList *paths;
	GError *err;

	if (argc<1) {
		g_printerr("Failed to add anything : expecting argument\r\n");
		abort();
	}

	err = NULL;
	if (!meta2_remote_container_open(&(cnx.addr), cnx.timeout.req, &err, cid)) {
		g_printerr("Failed to open the distant container : %s\r\n", gerror_get_message(err));
		g_clear_error(&err);
		return 0;
	}

	paths = build_paths_list(argc,args);
	si = meta2_remote_service_add_contents(&cnx, cid, service_name, paths, &err);
	_display_strlist("\tAdd wanted: ", paths);
	if (si == NULL) {
		g_printerr("Failed to insert a path : %s\r\n", gerror_get_message(err));
	} else {
		gchar str_addr[128];

		addr_info_to_string(&(si->addr), str_addr, sizeof(str_addr));
		g_printerr("Service found: %s\r\n", str_addr);
	}

	if (validation) {
		status_t rc0, rc1, rc2;
		
		/* COMMIT */
		rc0 = meta2_remote_service_commit_contents(&cnx,cid,service_name,paths,&commit_failed,&err);
		_display_strlist("\tCommit wanted: ", paths);
		_display_strlist("\tCommit succeeded: ", commit_failed); _gfree_list(&commit_failed);
		g_printerr("RESULT : %s\r\n", rc0 ? "ok" : gerror_get_message(err));

		if (rc0) {
			GError *e;
			gboolean rc_local;

			/* Second-COMMIT */
			e = NULL;
			rc_local = meta2_remote_service_commit_contents(&cnx,cid,service_name,paths,&commit_failed,&e);
			_display_strlist("\tSecond Commit wanted: ", paths);
			_display_strlist("\tSecond Commit failed: ", commit_failed);
			_gfree_list(&commit_failed);
			g_printerr("Second Commit RESULT : %s\r\n", rc_local ? "ok" : gerror_get_message(e));
		}

		/* DELETE */
		rc1 = meta2_remote_service_delete_contents(&cnx, cid, service_name, paths, &really_removed, &services_used, &err);
		_display_strlist("\tDelete wanted: ", paths);
		_display_strlist("\tservices used: ", services_used);
		_display_strlist("\tcontent removed : ", really_removed);
		_gfree_list(&services_used);
		_gfree_list(&really_removed);
		g_printerr("RESULT : %s\r\n", rc1 ? "ok" : gerror_get_message(err));

		/* COMMIT */
		rc2 = meta2_remote_service_commit_contents(&cnx,cid,service_name,paths,&commit_failed,&err);
		_display_strlist("\tCommit wanted: ", paths);
		_display_strlist("\tCommit succeeded: ", commit_failed);
		_gfree_list(&commit_failed);
		g_printerr("RESULT : %s\r\n", rc2 ? "ok" : gerror_get_message(err));

		if (!rc0 || !rc1 || !rc2)
			goto error_label;
	}
	else {
		status_t rc0, rc1, rc2;

		rc0 = rc1 = rc2 = ~0;

		/* ROLLBACK */
		rc0 = meta2_remote_service_rollback_contents(&cnx,cid,service_name,paths,&commit_failed,&err);
		_display_strlist("\tRollback wanted: ", paths);
		_display_strlist("\tRollback failed: ", commit_failed); _gfree_list(&commit_failed);
		g_printerr("RESULT : %s\r\n", rc0 ? "ok" : gerror_get_message(err));
		
		if (rc0) {
			GError *e;
			gboolean rc_local;

			/* Second-COMMIT */
			e = NULL;
			rc_local = meta2_remote_service_rollback_contents(&cnx,cid,service_name,paths,&commit_failed,&e);
			_display_strlist("\tSecond Rollback wanted: ", paths);
			_display_strlist("\tSecond Rollback failed: ", commit_failed); _gfree_list(&commit_failed);
			g_printerr("Second Rollback RESULT : %s\r\n", rc_local ? "ok" : gerror_get_message(e));
		}

		/* DELETE */
		rc1 = meta2_remote_service_delete_contents(&cnx, cid, service_name, paths, &really_removed, &services_used, &err);
		_display_strlist("\tDelete wanted: ", paths);
		_display_strlist("\tservices used: ", services_used);
		_display_strlist("\tcontent removed : ", really_removed);
		g_printerr("RESULT : %s\r\n", rc1 ? "ok" : gerror_get_message(err));

		if (services_used || really_removed) {
			g_printerr("ADD+ROLLBACK content should not be found\n");
			rc2 = 0;
		}
		
		if (!rc0 || !rc1 || !rc2)
			goto error_label;
	}

	meta2_remote_container_close_in_fd(cnx.fd, cnx.timeout.req, NULL, cid);
	return 1;
error_label:
	g_slist_free(paths);
	meta2_remote_container_close_in_fd(cnx.fd, cnx.timeout.req, NULL, cid);
	g_clear_error(&err);
	return 0;
}
Example #16
0
static int
add_event(gs_grid_storage_t * gs, const char *cName, const char *msg)
{
	int rc = -1;
	gs_error_t **gserr = NULL;
	gs_error_t *locerr = NULL;
	struct gs_container_location_s *location = NULL;
	container_id_t cid;
	struct metacnx_ctx_s cnx;
	gchar *hexid = NULL;
	gchar * meta2_url = NULL;
	GError *gerr = NULL;

	metacnx_clear(&cnx);
	if (!gs || !cName || !msg) {
		PRINT_ERROR("Invalid parameter (%p %p %p)\n", gs, cName, msg);
		return rc;
	}

	location = gs_locate_container_by_name(gs, cName, &locerr);
	if (!location) {
		PRINT_ERROR("cannot find %s\n", cName);
		goto exit_label;
	}
	if (!location->m0_url || !location->m1_url || !location->m2_url || !location->m2_url[0]) {
		PRINT_ERROR("cannot find %s\n", cName);
		goto exit_label;
	}
	PRINT_DEBUG("%s found\n", cName);
	hexid = location->container_hexid;
	meta2_url = location->m2_url[0];
	if (!container_id_hex2bin(hexid, strlen(hexid), &cid, &gerr)) {
		GSERRORCAUSE(gserr, gerr, "Invalid container id");
		goto exit_label;
	}

	if (!metacnx_init_with_url(&cnx, meta2_url, &gerr)) {
		GSERRORCAUSE(gserr, gerr, "Invalid META2 address");
		goto exit_label; 
	}

	container_event_t event;
	bzero(&event, sizeof(event));
	event.timestamp = time(0);
	g_strlcpy(event.type, "test", sizeof(event.type));
	g_strlcpy(event.ref, "test", sizeof(event.type));
	event.message = metautils_gba_from_string(msg);

	PRINT_DEBUG("Adding event [%s]", msg);
	rc = meta2_remote_add_container_event(&cnx, cid, &event, &gerr);

	g_byte_array_free(event.message, TRUE);
	event.message = NULL;

	metacnx_close(&cnx);
	metacnx_clear(&cnx);

	if (!rc) {
		PRINT_ERROR("Failed to add event : %s\n", gerror_get_message(gerr));
		g_clear_error(&gerr);
	}

exit_label:
	return rc;
}