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; }
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; }
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; }
/* * 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); }
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; }
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; }
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; }
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; }
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(); } } }
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; }