Пример #1
0
gboolean
conscience_srvtype_set_type_expression(struct conscience_srvtype_s * srvtype,
	GError ** err, const gchar * expr_str)
{
	struct expr_s *pE;

	if (!srvtype || !expr_str) {
		GSETCODE(err, ERRCODE_PARAM, "Invalid parameter");
		return FALSE;
	}

	pE = NULL;
	if (expr_parse(expr_str, &pE)) {
		GSETCODE(err, CODE_INTERNAL_ERROR, "Failed to parse the expression");
		return FALSE;
	}

	/*replaces the string */
	if (srvtype->score_expr_str)
		g_free(srvtype->score_expr_str);
	if (srvtype->score_expr)
		expr_clean(srvtype->score_expr);

	srvtype->score_expr_str = g_strdup(expr_str);
	srvtype->score_expr = pE;
	return TRUE;
}
Пример #2
0
gboolean
get_compression_info_in_attr(const char *pathname, GError ** error,
		GHashTable ** table)
{
	gchar *tmp;

	if (!table || !*table || !pathname) {
		SETERROR(error, "invalid parameter");
		return FALSE;
	}

	tmp = _getxattr_from_chunk(pathname, -1,
			ATTR_DOMAIN "." ATTR_NAME_CHUNK_METADATA_COMPRESS);

	if (!tmp) {
		if (errno != ENOATTR) {
			GSETCODE(error, errno, "Failed to get compression attr : %s\n", strerror(errno));
			return FALSE;
		}
	}
	else {
		if (*tmp) {
			GHashTable *ht = metadata_unpack_string(tmp, NULL);
			metadata_merge(*table, ht);
		}
		g_free(tmp);
	}

	return TRUE;
}
Пример #3
0
namespace_info_t *
namespace_info_unmarshall(const guint8 * buf, gsize buf_len, GError ** err)
{
	asn_dec_rval_t decRet;
	asn_codec_ctx_t codecCtx;
	namespace_info_t *result = NULL;
	NamespaceInfo_t *asn1_namespace_info = NULL;

	/*sanity checks */
	if (!buf) {
		GSETCODE(err, 500+EINVAL, "Invalid paremeter");
		return NULL;
	}

	/*deserialize the encoded form */
	codecCtx.max_stack_size = 65536;
	decRet = ber_decode(&codecCtx, &asn_DEF_NamespaceInfo, (void *) &asn1_namespace_info, buf, buf_len);
	if (decRet.code != RC_OK) {
		GSETCODE(err, 500, "Cannot deserialize: %s", (decRet.code == RC_WMORE)
				? "uncomplete data" : "invalid data");
		namespace_info_cleanASN(asn1_namespace_info, FALSE);
		return NULL;
	}

	/*prepare the working structures */
	if (!(result = g_try_malloc0(sizeof(namespace_info_t)))) {
		GSETCODE(err, 500+ENOMEM, "Memory allocation failure");
		namespace_info_cleanASN(asn1_namespace_info, FALSE);
		return NULL;
	}

	/*map the ASN.1 in a common structure */
	int rc = namespace_info_ASN2API(asn1_namespace_info, result);
	namespace_info_cleanASN(asn1_namespace_info, FALSE);
	asn1_namespace_info = NULL;
	if (rc) {
		errno = 0;
		return result;
	}

	namespace_info_free(result);
	result = NULL;

	GSETCODE(err, 500, "ASN.1 to API mapping failure");
	return NULL;
}
Пример #4
0
/*
 * Do the job of scan_volume() with the ability to be called recursively
 *
 * @param str_dir
 * @param matching_glob
 * @param callback
 * @param callback_data
 * @param sleep_time
 * @param error
 *
 * @return TRUE or FALSE if an error occured (error is set)
 */
static enum scanner_traversal_e
_recursive_scan_dir(const gchar * str_dir, guint depth, struct volume_scanning_info_s *scanning_info, struct rules_motor_env_s** motor)
{
	enum scanner_traversal_e rc = SCAN_CONTINUE;
	struct stat dir_stat;
	struct dirent **namelist;
	int i, nb_names;

	enum scanner_traversal_e notify_error(void) {
		enum scanner_traversal_e local_rc;
		GError *err;

		if (!scanning_info->error)
			return SCAN_CONTINUE;

		err = NULL;
		GSETCODE(&err, errno, "Failed to scan dir [%s] : %s", str_dir, strerror(errno));
		local_rc = scanning_info->error(str_dir, err, scanning_info->callback_data);
		g_error_free(err);

		if (local_rc == SCAN_ABORT)
			return SCAN_ABORT;
		return SCAN_STOP_BRANCH;
	}

	/*
	   Define select func here because we need the matching_glob inside
	   and have no way to pass it through the scandir
	 */
	int select_file(const struct dirent *file)
	{
		int rc_stat;
		struct stat path_stat;

		if (!is_not_special_dir(file))
			return 0;

		do {
			gchar *fullpath = g_strconcat(str_dir, G_DIR_SEPARATOR_S, file->d_name, NULL);
			rc_stat = stat(fullpath, &path_stat);
			g_free(fullpath);
		} while (0);

		if (-1 == rc_stat)
			return 0;

		if (S_ISDIR(path_stat.st_mode))
			return 1;

		return scanning_info->file_match(str_dir, file->d_name,
				scanning_info->callback_data);
	}
Пример #5
0
gboolean
get_chunk_compressed_size_in_attr(const char *pathname, GError ** error, guint32* compressed_size)
{
	gchar* tmp = NULL;

	if (!(tmp = _getxattr_from_chunk(pathname, -1, ATTR_DOMAIN "." ATTR_NAME_CHUNK_COMPRESSED_SIZE))) {
		GSETCODE(error, errno, "compressedsize not found : %s", strerror(errno));
		return FALSE;
	}

	*compressed_size = g_ascii_strtoll(tmp, NULL, 10);
	g_free(tmp);
	return TRUE;
}
Пример #6
0
struct conscience_srv_s *
conscience_srvtype_register_srv(struct conscience_srvtype_s *srvtype,
    GError ** err, const struct conscience_srvid_s *srvid)
{
	gsize desc_size;
	struct conscience_srv_s *service;

	if (!srvtype || !srvid) {
		GSETCODE(err, CODE_INTERNAL_ERROR, "Invalid parameter");
		return NULL;
	}

	service = g_malloc0(sizeof(struct conscience_srv_s));
	memcpy(&(service->id), srvid, sizeof(struct conscience_srvid_s));
	service->tags = g_ptr_array_new();
	service->locked = FALSE;
	service->score.timestamp = 0;
	service->score.value = -1;
	service->srvtype = srvtype;

	/*build the service description once for all*/
	desc_size = g_snprintf(service->description,sizeof(service->description),"%s/%s/",
		srvtype->conscience->ns_info.name, srvtype->type_name);
	grid_addrinfo_to_string(&(service->id.addr),
		service->description+desc_size,sizeof(service->description)-desc_size);

	/*register the service with its ID*/
	g_hash_table_insert(srvtype->services_ht, &(service->id), service);

	/*ring insertion */
	srvtype->services_ring.next->prev = service;
	service->prev = &(srvtype->services_ring);

	service->next = srvtype->services_ring.next;
	srvtype->services_ring.next = service;

	return service;
}
Пример #7
0
static gboolean
_rawx_update_chunk_attrs(chunk_id_t *cid, GSList *attrs, GError **err)
{
	ne_session *s = NULL;
	ne_request *r = NULL;
	int ne_rc;
	gboolean result = FALSE;

	gchar dst[128];
	guint16 port = 0;
	GString *req_str = NULL;
	char idstr[65];

	if (!addr_info_get_addr(&(cid->addr), dst, sizeof(dst), &port))
		return result;

	s = ne_session_create("http", dst, port);
	if (!s) {
		GSETERROR(err, "Failed to create session to rawx %s:%d", dst, port);
		return result;
	}

	ne_set_connect_timeout(s, 10);
	ne_set_read_timeout(s, 30);

	req_str =g_string_new("/rawx/chunk/set/");
	bzero(idstr, sizeof(idstr));
	buffer2str(&(cid->id), sizeof(cid->id), idstr, sizeof(idstr));
	req_str = g_string_append(req_str, idstr);
	GRID_TRACE("Calling %s", req_str->str);

	r = ne_request_create (s, "GET", req_str->str);
	if (!r) {
		goto end_attr;
	}

	for (; attrs != NULL; attrs = attrs->next) {
		struct chunk_attr_s *attr = attrs->data;
		ne_add_request_header(r, attr->key, attr->val);
	}

	switch (ne_rc = ne_request_dispatch(r)) {
		case NE_OK:
			result = TRUE;
			break;
		case NE_ERROR:
			GSETCODE(err, 500, "Request NE_ERROR");
			break;
		case NE_TIMEOUT:
			GSETCODE(err, 500, "Request Timeout");
			break;
		case NE_CONNECT:
			GSETCODE(err, 500, "Request Connection timeout");
			break;
		default:
			GSETCODE(err, 500, "Request failed");
			break;
	}

end_attr:
	if (NULL != req_str)
		g_string_free(req_str, TRUE);
	if (NULL != r)
		ne_request_destroy (r);
	if (NULL != s)
		ne_session_destroy (s);

	return result;
}
Пример #8
0
gboolean
conscience_run_srvtypes(struct conscience_s * conscience, GError ** error, guint32 flags,
    gchar ** names_array, service_callback_f * callback, gpointer udata)
{
	gboolean rc;
	register guint i, max;
	register guint32 real_flags;
	gchar **name;
	GPtrArray *array_srvtypes;

	if (!conscience || !names_array || !callback) {
		GSETERROR(error, "Invalid parameter (conscience=%p names_array=%p callback=%p)",
		    conscience, names_array, callback);
		return FALSE;
	}

	array_srvtypes = g_ptr_array_sized_new(8);
	rc = TRUE;

	/* XXX start of critical version */
	if (flags & SRVTYPE_FLAG_LOCK_ENABLE)
		conscience_lock_srvtypes(conscience, 'r');

	/*We do not run any service type if we are not sure that all exist */
	for (name = names_array; *name; name++) {
		struct conscience_srvtype_s *srvtype;

		srvtype = conscience_get_srvtype(conscience, error, *name, MODE_STRICT);
		if (!srvtype) {
			rc = FALSE;
			GSETCODE(error, 460, "Service type [%s] not managed", *name);
			goto unlock_and_exit;
		}
		g_ptr_array_add(array_srvtypes, srvtype);
	}

	/*we remove the additional call, we just want one call at the end */
	real_flags = flags & ~SRVTYPE_FLAG_ADDITIONAL_CALL;

	for (i = 0, max = array_srvtypes->len; rc && i < max; i++) {
		struct conscience_srvtype_s *srvtype;

		srvtype = g_ptr_array_index(array_srvtypes, i);

		if (flags & SRVTYPE_FLAG_LOCK_ENABLE) {
			/* XXX start of critical section */
			if (flags & SRVTYPE_FLAG_LOCK_WRITER)
				g_static_rw_lock_writer_lock(&(srvtype->rw_lock));
			else
				g_static_rw_lock_reader_lock(&(srvtype->rw_lock));
		}

		rc = conscience_srvtype_run_all(srvtype, error, real_flags, callback, udata);

		if (flags & SRVTYPE_FLAG_LOCK_ENABLE) {
			if (flags & SRVTYPE_FLAG_LOCK_WRITER)
				g_static_rw_lock_writer_unlock(&(srvtype->rw_lock));
			else
				g_static_rw_lock_reader_unlock(&(srvtype->rw_lock));
			/* XXX end of critical section */
		}

		if (!rc) {
			GSETERROR(error, "An error occured while running the services of type [%s]", srvtype->type_name);
			goto unlock_and_exit;
		}
	}

	if (rc && (flags & SRVTYPE_FLAG_ADDITIONAL_CALL))
		rc = callback(NULL, udata);

      unlock_and_exit:

	if (flags & SRVTYPE_FLAG_LOCK_ENABLE)
		conscience_unlock_srvtypes(conscience);
	/* XXX end of critical version */

	g_ptr_array_free(array_srvtypes, TRUE);
	return rc;
}
Пример #9
0
gint
sock_to_read(int fd, gint ms, void *buf, gsize bufSize, GError ** err)
{
	if (VTABLE.to_read)
		return VTABLE.to_read(fd, ms, buf, bufSize, err);

#define READ() do { \
		rc = metautils_syscall_read(fd, buf, bufSize); \
		if (rc > 0) \
			return rc; \
		if (rc == 0) { \
			GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d closed", fd); \
			return 0; \
		} \
		if (errno != EAGAIN && errno != EINTR) { \
			GSETCODE(err, errno_to_errcode(errno), "Read error (%s)", strerror(errno)); \
			return -1; \
		} \
	} while (0)

	gint rc;

	if (fd < 0 || !buf || bufSize <= 0) {
		GSETERROR(err, "invalid parameter");
		return -1;
	}

	/* on tente un premier READ, qui s'il reussit, nous epargne un appel a POLL */
	READ();

	/* pas de data en attente, donc attente protegee par le poll */
	for (;;) {
		struct pollfd p;

		p.fd = fd;
		p.events = POLLIN;
		p.revents = 0;

		/*wait for something to happen */
		rc = metautils_syscall_poll(&p, 1, ms);
		if (rc == 0) {	/*timeout */
			GSETCODE(err, ERRCODE_CONN_TIMEOUT, "Socket timeout");
			return -1;
		}

		if (rc < 0 && errno != EINTR) {	/*error */
			GSETCODE(err, errno_to_errcode(errno), "Socket error (%s)", strerror(errno));
			return -1;
		}
		if (rc == 1) {
			if (p.revents & POLLHUP && !(p.revents & POLLIN)) {
				GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d closed", fd);
				return 0;
			}
			if (p.revents & POLLERR) {
				int sock_err = socket_get_errcode(fd);
				GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d error : (%d) %s", fd, sock_err, strerror(sock_err));
				return 0;
			}
			READ();
		}
	}
}
Пример #10
0
gint
sock_to_write(int fd, gint ms, void *buf, gsize bufSize, GError ** err)
{
	if (VTABLE.to_write)
		return VTABLE.to_write(fd, ms, buf, bufSize, err);

#define WRITE() do { \
		written = metautils_syscall_write(fd, ((guint8 *)buf) + nbSent, bufSize - nbSent); \
		if (written > 0) { \
			ui_written = written; \
			nbSent += ui_written; \
		} \
		if (written < 0) { \
			if (errno != EAGAIN && errno != EINTR) { \
				GSETERROR(err, "Write error (%s)", strerror(errno)); \
				return -1; \
			} \
		} \
} while (0)

	gsize ui_written;
	ssize_t written;
	gsize nbSent = 0;

	if (fd < 0 || !buf || bufSize <= 0) {
		GSETERROR(err, "invalid parameter");
		return -1;
	}

	WRITE();

	while (nbSent < bufSize) {
		int rc_poll;
		struct pollfd p;

		p.fd = fd;
		p.events = POLLOUT | POLLERR | POLLHUP | POLLNVAL;
		p.revents = 0;

		errno = 0;
		rc_poll = metautils_syscall_poll(&p, 1, ms);

		if (rc_poll == 0) {	/*timeout */
			GSETCODE(err, ERRCODE_CONN_TIMEOUT, "Socket timeout");
			return (-1);
		}

		if (rc_poll == -1) {	/*poll error */
			if (errno != EINTR) {
				GSETERROR(err, "Socket error (%s) after %"G_GSIZE_FORMAT" bytes written", strerror(errno), nbSent);
				return (-1);
			}
			else {
				TRACE("poll interrupted (%s)", strerror(errno));
				continue;
			}
		}

		/*poll success */
		if (p.revents & POLLNVAL) {
			GSETERROR(err, "Socket (%d) is invalid after %"G_GSIZE_FORMAT" bytes sent", fd, nbSent);
			return -1;
		}
		if (p.revents & POLLERR) {
			int sock_err = socket_get_errcode(fd);
			GSETERROR(err, "Socket (%d) error after %"G_GSIZE_FORMAT" bytes written : (%d) %s", fd, nbSent, sock_err, strerror(sock_err));
			return -1;
		}
		if ((p.revents & POLLHUP)) {
			GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket (%d) closed after %"G_GSIZE_FORMAT" bytes written", fd, nbSent);
			return -1;
		}

		WRITE();
	}

	return nbSent;
}