void stop_server(void) { DEBUG("Stopping the server..."); if (sock_unix >= 0) { remove_fd_from_io_scheduler(&worker_unix, NULL); metautils_pclose(&sock_unix); unlink(unix_socket_path); } if (sock_inet >= 0) { remove_fd_from_io_scheduler(&worker_inet, NULL); metautils_pclose(&sock_inet); } DEBUG("The server is stopped."); }
void stop_server(void) { DEBUG("Stopping the server..."); if (usock>=0) { remove_fd_from_io_scheduler(&worker_unix, NULL); metautils_pclose(&usock); } if (sock_inet>=0) { remove_fd_from_io_scheduler(&worker_inet, NULL); metautils_pclose(&sock_inet); } unlink(AGENT_SOCK_PATH); DEBUG("The server is stopped."); }
static gboolean _commit_attr_handle(struct attr_handle_s *attr_handle, GError ** error) { GError *local_error = NULL; if (attr_handle == NULL) { SETERRCODE(error, EINVAL, "Invalid attr_handle argument"); return FALSE; } /* try to write the chunk extended attributes */ attr_handle->chunk_file_des = open(attr_handle->chunk_path, O_RDWR); if (attr_handle->chunk_file_des >= 0) { if (_write_attributes(attr_handle->attr_hash, attr_handle->chunk_file_des, _write_to_xattr, &local_error)) { metautils_pclose(&(attr_handle->chunk_file_des)); return TRUE; } else { /*WARN("Failed to write attributes to chunk xattr : %s", local_error->message);*/ metautils_pclose(&(attr_handle->chunk_file_des)); g_clear_error(&local_error); } } /* Fallback to .attr file */ attr_handle->attr_file_des = open(attr_handle->attr_path, O_RDWR | O_CREAT | O_TRUNC, 0644); if (attr_handle->attr_file_des < 0) { SETERRCODE(error, errno, "File [%s] open failed : %s", attr_handle->attr_path, strerror(errno)); return FALSE; } else { if (!_write_attributes(attr_handle->attr_hash, attr_handle->attr_file_des, _write_to_attr_file, &local_error)) { metautils_pclose(&(attr_handle->attr_file_des)); SETERROR(error, "Failed to write attributes to chunk.attr : %s", local_error->message); g_clear_error(&local_error); return FALSE; } metautils_pclose(&(attr_handle->attr_file_des)); } return TRUE; }
static void _endpoint_close (struct endpoint_s *u) { if (!u) return; if (u->fd >= 0) { if (_endpoint_is_UNIX (u)) (void) unlink (u->url); metautils_pclose(&(u->fd)); } u->port_real = 0; }
/** * FIXME TODO XXX file load duplicated at cluster/lib/gridcluster.c : gba_read() */ static int cpu_stat_task_worker(gpointer udata, GError ** error) { char end_of_buffer = '\0'; int fd = 0; ssize_t rl; char *procstat = NULL; GByteArray *buffer = NULL; char buff[DEFAULT_BUFFER_SIZE]; proc_stat_t pstat; (void)udata; fd = open(PROC_STAT, O_RDONLY); if (fd < 0) { GSETERROR(error, "Failed to open file [%s] : %s", PROC_STAT, strerror(errno)); task_done(TASK_ID); return 0; } buffer = g_byte_array_new(); while ((rl = read(fd, buff, DEFAULT_BUFFER_SIZE)) > 0) buffer = g_byte_array_append(buffer, (guint8*)buff, rl); metautils_pclose(&fd); if (rl < 0) { GSETERROR(error, "Read file [%s] failed with error : %s", PROC_STAT, strerror(errno)); g_byte_array_free(buffer, TRUE); task_done(TASK_ID); return 0; } /*ensure the statistics string is NULL-terminated */ g_byte_array_append(buffer, (guint8*)&end_of_buffer, sizeof(end_of_buffer)); procstat = (char*)g_byte_array_free(buffer, FALSE); memset(&pstat, 0, sizeof(proc_stat_t)); if (sscanf(procstat, "cpu %llu %llu %llu %llu %llu %llu %llu", &(pstat.user), &(pstat.nice), &(pstat.system), &(pstat.idle), &(pstat.io_wait), &(pstat.irq), &(pstat.soft_irq)) == 7) { memcpy(&(cpu_stat.previous), &(cpu_stat.current), sizeof(proc_stat_t)); memcpy(&(cpu_stat.current), &pstat, sizeof(proc_stat_t)); nb_loops++; } else { WARN("Failed to scan cpu in string [%s]", procstat); } g_free(procstat); task_done(TASK_ID); return (1); }
static int check_socket_is_absent( struct working_parameter_s *pParam, GError **err ) { struct sockaddr_un sun; int attempts, fd, rc; struct stat lStat; for (attempts=3; attempts>0 ; attempts--) { if (-1==stat( pParam->path.ptr, &lStat )) { switch (errno) { case ENOTDIR: case EACCES: case ELOOP: GSETERROR(err,"cannot access the socket path : %s", strerror(errno)); return -1; default: return 0; } } else { if (!S_ISSOCK(lStat.st_mode)) { GSETERROR(err,"path %s exists and is not a socket, remove it and restart the server", pParam->path.ptr); return -1; } if (-1==(fd = socket(PF_LOCAL, SOCK_STREAM, 0))) { GSETERROR(err,"socket error : %s", strerror(errno)); return -1; } /*try to connect*/ sun.sun_family = PF_LOCAL; strncpy(sun.sun_path, pParam->path.ptr, sizeof(sun.sun_path)); rc = connect(fd,(struct sockaddr*)&sun,sizeof(sun)); metautils_pclose(&fd); if (!rc) { GSETERROR(err,"Server socket already up at [%s]", pParam->path.ptr); return -1; } else if (-1==unlink(pParam->path.ptr)) { GSETERROR(err,"Cannot remove the socket at [%s] : %s", pParam->path.ptr, strerror(errno)); return -1; } /*else the socket has been unlinked, we retry to connect*/ NOTICE("Socket %s unlinked", pParam->path.ptr); } } GSETERROR(err, "Supposed socket [%s] could not be removed", pParam->path.ptr); return -1; }
static void _destroy(struct gridd_client_pool_s *pool) { if (!pool) return; EXTRA_ASSERT(pool->vtable == &VTABLE); pool->closed = ~0; if (pool->fd_in >= 0) metautils_pclose(&(pool->fd_in)); if (pool->fd_out >= 0) metautils_pclose(&(pool->fd_out)); if (pool->fdmon >= 0) metautils_pclose(&(pool->fdmon)); if (pool->pending_clients) { struct event_client_s *ec; while (NULL != (ec = g_async_queue_try_pop(pool->pending_clients))) event_client_free(ec); g_async_queue_unref(pool->pending_clients); pool->pending_clients = NULL; } if (pool->active_clients) { for (int i=0; i<pool->active_clients_size ;i++) { struct event_client_s *ec = pool->active_clients[i]; pool->active_clients[i] = NULL; if (ec) event_client_free(ec); } g_free(pool->active_clients); pool->active_clients = NULL; } g_free(pool); }
int socket_nonblock(int domain, int type, int protocol) { if (VTABLE.socket_nonblock) return VTABLE.socket_nonblock(domain, type, protocol); #ifdef HAVE_SOCKET3 return metautils_syscall_socket(domain, type|SOCK_NONBLOCK, protocol); #else int fd = metautils_syscall_socket(domain, type, protocol); if (fd < 0) return fd; if (sock_set_non_blocking(fd, TRUE)) return fd; metautils_pclose(&fd); return -1; #endif }
static void sighandler_config(int s) { switch (s) { case SIGUSR1: case SIGUSR2: case SIGCHLD: break; case SIGPIPE: metautils_pclose(&fd_out); break; case SIGTERM: case SIGQUIT: case SIGINT: is_running = FALSE; break; } signal(s, sighandler_config); }
gs_error_t * hc_get_content(gs_grid_storage_t *hc, struct hc_url_s *url, const char *local_path, int force, int cache, gchar *stgpol) { gs_error_t *e = NULL; /* download a content */ gs_download_info_t dl_info; int out = 0; memset(&dl_info, 0x00, sizeof(dl_info)); if(_open_destination(local_path, force, &out)) { GRID_DEBUG("Destination file descriptor ready fd=%d path=%s\n", out, local_path ? local_path : "<stdout>"); /*download the content */ dl_info.offset = 0; dl_info.size = 0; dl_info.writer = _write_to_fd; dl_info.user_data = &out; e = hc_dl_content(hc, url, &dl_info, cache, stgpol); if (out >= 0) { metautils_pclose(&out); } if (e) { g_printerr("Cannot download %s from %s (into %s)\n", hc_url_get(url, HCURL_PATH), hc_url_get(url, HCURL_REFERENCE), local_path ? local_path : "<stdout>"); } else { GRID_DEBUG("Download done from %s to %s\n", hc_url_get(url, HCURL_PATH), local_path ? local_path : "<stdout>"); } } else { gchar tmp[256]; bzero(tmp, sizeof(tmp)); g_snprintf(tmp, sizeof(tmp), "Failed to open the destination file descriptor to path=%s\n", local_path ? local_path : "<stdout>"); e = g_malloc0(sizeof(gs_error_t)); e->code = 0; e->msg = g_strdup(tmp); } return e; }
static void _population_create(const gchar *basedir, struct citizen_s *population) { for (; population->dirname ; ++population) { gchar *dn = g_strconcat(basedir, G_DIR_SEPARATOR_S, population->dirname, NULL); if (0 != g_mkdir_with_parents(dn, 0700)) g_error("Try error: mkdir(%s) : (%d) %s", dn, errno, strerror(errno)); if (population->basename && population->basename[0]) { gchar *full = g_strconcat(dn, G_DIR_SEPARATOR_S, population->basename, NULL); int fd = open(full, O_CREAT|O_TRUNC|O_SYNC, 0600); if (fd < 0) g_error("Try error: open(%s) : (%d) %s", full, errno, strerror(errno)); metautils_pclose(&fd); g_free(full); } g_free(dn); } }
static int _uconnect_path(const gchar *path, GError **err) { struct sockaddr_un local; memset(&local, 0x00, sizeof(local)); local.sun_family = AF_UNIX; g_strlcpy(local.sun_path, path, sizeof(local.sun_path)); int usock = socket_nonblock(PF_UNIX, SOCK_STREAM, 0); if (usock < 0) { GSETERROR(err, "socket(UNIX): (%d) %s", errno, strerror(errno)); return -1; } if (0 > connect(usock, (struct sockaddr *) &local, sizeof(local))) { GSETERROR(err, "connect(%s): (%d) %s", path, errno, strerror(errno)); metautils_pclose(&usock); return -1; } return usock; }
static int read_known_service_from_file(GArray *known_services, const char *file_name, GError **error) { int fd; guint8 buff[256]; ssize_t r; GByteArray *data = NULL; int service_number = 0; struct grid_service_data *services = NULL; fd = open(file_name, O_RDONLY); if (fd < 0) { GSETERROR(error, "Failed to open file [%s] : %s", file_name, strerror(errno)); return(0); } data = g_byte_array_new(); while ((r = read(fd, buff, sizeof(buff))) > 0) { data = g_byte_array_append(data, buff, r); } metautils_pclose(&fd); if (r < 0) { GSETERROR(error, "Failed to read data from file [%s] : %s", file_name, strerror(errno)); g_byte_array_free(data, TRUE); return(0); } service_number = ( data->len * sizeof(guint8) ) / sizeof(struct grid_service_data); services = (struct grid_service_data *)g_byte_array_free(data, FALSE); known_services = g_array_append_vals(known_services, services, service_number); g_free(services); return(1); }
static void _client_clean(struct network_server_s *srv, struct network_client_s *clt) { (void) srv; /* Notifies the upper layer the client is being exiting. */ if (clt->transport.notify_error) clt->transport.notify_error(clt); EXTRA_ASSERT(clt->prev == NULL); EXTRA_ASSERT(clt->next == NULL); EXTRA_ASSERT(clt->fd >= 0); metautils_pclose(&(clt->fd)); _cnx_notify_close(srv); clt->local_stats = NULL; clt->main_stats = NULL; clt->flags = clt->events = 0; memset(&(clt->time), 0, sizeof(clt->time)); data_slab_sequence_clean_data(&(clt->input)); data_slab_sequence_clean_data(&(clt->output)); clt->input.first = clt->input.last = NULL; clt->output.first = clt->output.last = NULL; /* clean the transport, if any */ struct network_transport_s *t = &(clt->transport); if (t->client_context && t->clean_context) t->clean_context(t->client_context); memset(t, 0x00, sizeof(*t)); if (clt->current_error) g_clear_error(&(clt->current_error)); SLICE_FREE(struct network_client_s, clt); }
gint accept_close_servers (ACCEPT_POOL ap, GError **err) { int *pSrv = NULL; int max=0, nb_errors=0; if (!ap) { GSETERROR(err,"Invalid parameter"); return 0; } g_rec_mutex_lock (&(ap->mut)); if (ap->srv) { pSrv = ap->srv; max = ap->count; } ap->srv = NULL; ap->count = 0; g_rec_mutex_unlock (&(ap->mut)); if (pSrv) { int i; for (i=0; i<max ;i++) { int fd = pSrv[ i ]; if (fd>=0) { remove_unix_socket( fd ); errno=0; metautils_pclose(&fd); } pSrv[ i ] = -1; } } g_free(pSrv); return nb_errors; }
int send_request(request_t *req, response_t *resp, GError **error) { int fd; size_t size_to_send, u_size_sent, u_size_read; gint size_sent, size_read; message_t message; void *buff = NULL; memset(&message, 0, sizeof(message_t)); if (!build_message_from_request(&message, req, error)) { GSETERROR(error, "Failed to build message"); return(0); } if (!connect_socket(&fd, error)) { GSETERROR(error, "Connection to agent failed"); goto error_connect; } size_to_send = message.length + sizeof(message.length); buff = g_try_malloc0(size_to_send); if (buff == NULL) { GSETERROR(error, "Memory allocation failure"); goto error_alloc_buff; } memcpy(buff, &(message.length), sizeof(message.length)); memcpy(buff + sizeof(message.length), message.data, message.length); size_sent = sock_to_write(fd, CONNECT_TIMEOUT, buff, size_to_send, error); if (size_sent<0) { GSETERROR(error, "Failed to send all data to agent"); goto error_write; } if ((u_size_sent=size_sent) < size_to_send) { GSETERROR(error, "Failed to send all data to agent"); goto error_write; } /* Clean message to reuse it */ message_clean( &message); size_read = sock_to_read_size(fd, SOCKET_TIMEOUT, &(message.length), sizeof(message.length), error); if ((u_size_read=size_read) < sizeof(message.length)) { GSETERROR(error, "Failed to read message size"); goto error_read_size; } message.data = g_try_malloc0(message.length); if (message.data == NULL) { GSETERROR(error, "Memory allocation failure"); goto error_alloc_data; } size_read = sock_to_read_size(fd, SOCKET_TIMEOUT, message.data, message.length, error); if ((u_size_read=size_read) < message.length) { GSETERROR(error, "Failed to read all data from agent"); goto error_read; } if (!read_response_from_message(resp, &message, error)) { GSETERROR(error, "Failed to extract response from message"); goto error_read_resp; } metautils_pclose(&fd); g_free(buff); message_clean( &message); return(1); error_read_resp: error_read: error_alloc_data: error_read_size: error_write: if (buff) g_free(buff); error_alloc_buff: metautils_pclose(&fd); error_connect: message_clean( &message); return(0); }
static GError * _endpoint_open(struct endpoint_s *u) { EXTRA_ASSERT(u != NULL); struct sockaddr_storage ss; socklen_t ss_len = sizeof(ss); memset(&ss, 0, sizeof(ss)); /* patch some socket preferences that make sense only for INET sockets */ if (_endpoint_is_UNIX(u)) { u->port_real = 0; u->port_cfg = 0; u->flags &= ~(NETSERVER_THROUGHPUT|NETSERVER_LATENCY); } /* Get a socket of the right type */ if (_endpoint_is_UNIX(u)) u->fd = socket(AF_UNIX, SOCK_STREAM, 0); else if (_endpoint_is_INET6(u)) u->fd = socket(AF_INET6, SOCK_STREAM, 0); else u->fd = socket(AF_INET, SOCK_STREAM, 0); if (u->fd < 0) return NEWERROR(errno, "socket() = '%s'", strerror(errno)); if (_endpoint_is_INET(u)) sock_set_reuseaddr (u->fd, TRUE); /* Bind the socket the right way according to its type */ if (_endpoint_is_UNIX(u)) { struct sockaddr_un *sun = (struct sockaddr_un*) &ss; ss_len = sizeof(*sun); sun->sun_family = AF_UNIX; g_strlcpy(sun->sun_path, u->url, sizeof(sun->sun_path)); } else if (_endpoint_is_INET6(u)) { struct sockaddr_in6 *s6 = (struct sockaddr_in6*) &ss; ss_len = sizeof(*s6); s6->sin6_family = AF_INET6; s6->sin6_port = htons(u->port_cfg); inet_pton(AF_INET6, u->url, &(s6->sin6_addr)); } else { struct sockaddr_in *s4 = (struct sockaddr_in*) &ss; ss_len = sizeof(*s4); s4->sin_family = AF_INET; s4->sin_port = htons(u->port_cfg); inet_pton(AF_INET, u->url, &(s4->sin_addr)); } if (0 > bind(u->fd, (struct sockaddr*)&ss, ss_len)) { int errsave = errno; u->port_real = 0; if (_endpoint_is_UNIX(u)) metautils_pclose (&u->fd); return NEWERROR(errsave, "bind(%s) = '%s'", u->url, strerror(errsave)); } /* for INET sockets, get the port really used */ if (_endpoint_is_INET(u)) { memset(&ss, 0, sizeof(ss)); ss_len = sizeof(ss); getsockname(u->fd, (struct sockaddr*)&ss, &ss_len); if (_endpoint_is_INET4(u)) u->port_real = ntohs(((struct sockaddr_in*)&ss)->sin_port); else u->port_real = ntohs(((struct sockaddr_in6*)&ss)->sin6_port); } /* And finally set the mandatory fags. */ sock_set_non_blocking(u->fd, TRUE); if (0 > listen(u->fd, 32768)) return NEWERROR(errno, "listen() = '%s'", strerror(errno)); return NULL; }
static GError * _client_manage_reply(struct gridd_client_s *client, MESSAGE reply) { GError *err; guint status = 0; gchar *message = NULL; if (NULL != (err = metaXClient_reply_simple(reply, &status, &message))) { g_prefix_error (&err, "reply: "); return err; } if (CODE_IS_NETWORK_ERROR(status)) { err = NEWERROR(status, "net error: %s", message); g_free(message); metautils_pclose(&(client->fd)); client->step = STATUS_FAILED; return err; } if (status == CODE_TEMPORARY) { g_get_current_time(&(client->tv_step)); client->step = REP_READING_SIZE; g_free(message); return NULL; } if (CODE_IS_OK(status)) { g_get_current_time(&(client->tv_step)); client->step = (status==CODE_FINAL_OK) ? STATUS_OK : REP_READING_SIZE; if (client->step == STATUS_OK) { if (!client->keepalive) metautils_pclose(&(client->fd)); } g_free(message); if (client->on_reply) { if (!client->on_reply(client->ctx, reply)) return NEWERROR(CODE_INTERNAL_ERROR, "Handler error"); } return NULL; } if (status == CODE_REDIRECT) { /* Reset the context */ _client_reset_reply(client); _client_reset_cnx(client); client->sent_bytes = 0; if ((++ client->nb_redirects) > 7) { g_free(message); return NEWERROR(CODE_TOOMANY_REDIRECT, "Too many redirections"); } /* Save the current URL to avoid looping, and check * for a potential loop */ g_string_append_c(client->past_url, '|'); g_string_append(client->past_url, client->url); if (_client_looped(client, message)) { g_free(message); return NEWERROR(CODE_LOOP_REDIRECT, "Looping on redirections"); } /* Replace the URL */ memset(client->url, 0, sizeof(client->url)); g_strlcpy(client->url, message, sizeof(client->url)-1); if (NULL != (err = _client_connect(client))) { g_free(message); g_prefix_error(&err, "Redirection error: Connect error: "); return err; } g_free(message); return NULL; } /* all other are considered errors */ err = NEWERROR(status, "Request error: %s", message); g_free(message); if (!client->keepalive) _client_reset_cnx(client); _client_reset_reply(client); return err; }
int uncompress_chunk2(const gchar* path, gboolean preserve, gboolean keep_pending, GError ** error) { GError *local_error = NULL; int status = 0; TRACE("Uncompressing [%s]", path); gchar *tmp_path = NULL; gulong tmp_len; gint64 total_read; guint8* data = NULL; gint64 bufsize, nb_read; gint64 current_read; struct stat *buf = NULL; struct compressed_chunk_s *cp_chunk = NULL; struct compression_ctx_s *comp_ctx = NULL; FILE *dst = NULL; /* Check chunk exists */ buf = g_malloc0(sizeof(struct stat)); DEBUG("Checking chunk exists"); if(stat(path, buf) == -1) { GSETERROR (error, "stat() failed, chunk not found\n"); goto end; } DEBUG("File [%s] found", path); GHashTable *compress_opt = NULL; compress_opt = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free); if(!get_compression_info_in_attr(path, error, &compress_opt)) { GSETERROR(error, "Failed to get compression info in attr, chunk may be not compressed"); goto end; } gchar * compression = NULL; compression = (gchar*) g_hash_table_lookup(compress_opt, NS_COMPRESSION_OPTION); if (compression != NULL && g_ascii_strncasecmp(compression, NS_COMPRESSION_ON, strlen(compression)) != 0) { GSETERROR(error, "Chunk not compressed, cannot nothing to do"); goto end; } /* init compression method according to algo choice */ comp_ctx = g_malloc0(sizeof(struct compression_ctx_s)); init_compression_ctx(comp_ctx, g_hash_table_lookup(compress_opt, NS_COMPRESS_ALGO_OPTION)); cp_chunk = g_malloc0(sizeof(struct compressed_chunk_s)); if (comp_ctx->chunk_initiator(cp_chunk, path) != 0) { GSETERROR(error, "Failed to init compressed chunk context"); goto end; } DEBUG("Chunk check done"); tmp_len = strlen(path) +sizeof(".pending"); tmp_path = g_malloc0(tmp_len); g_snprintf(tmp_path, tmp_len, "%s.pending", path); DEBUG("Checking chunk not busy"); if(stat(tmp_path, buf) != -1) { DEBUG("Stats failed"); GSETERROR (error, "stat() success on pending file, cannot process : busy chunk\n"); goto end; } do { int fd; if((fd = open(tmp_path, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1) { GSETERROR(error, "Failed to create pending chunk file (%s)\n", strerror(errno)); goto end; } metautils_pclose(&fd); } while (0); if(!copy_fattr(path, tmp_path, error)) { GSETERROR(error, "Failed to copy extended attributes to destination file\n"); goto end; } TRACE("xattr copied from src to dst"); dst = fopen(tmp_path, "w"); TRACE("Destination file opened"); gint64 chunk_size; chunk_size = g_ascii_strtoll(cp_chunk->uncompressed_size, NULL, 10); total_read = 0; DEBUG("Starting, total_read = %"G_GINT64_FORMAT", chunk_size = %"G_GINT64_FORMAT, total_read, chunk_size); while(total_read < chunk_size) { bufsize = MIN(DECOMPRESSION_MAX_BUFSIZE, (chunk_size - total_read)); data = g_malloc0(bufsize); DEBUG("New buffer allocated sized %"G_GINT64_FORMAT" bytes", bufsize); nb_read = 0; current_read = 0; while(nb_read < bufsize) { current_read = comp_ctx->data_uncompressor(cp_chunk, 0, data + nb_read, bufsize - nb_read, &local_error); DEBUG("Currently read %"G_GINT64_FORMAT" bytes", current_read); if(current_read < 0) { if(local_error) { GSETERROR(error, "An error occured while decompressing chunk : %s", local_error->message); g_clear_error(&local_error); } else GSETERROR(error, "An error occured while decompressing chunk\n"); goto end; } else if (current_read == 0) { /* Premature end of file, will still write to pending */ WARN("Read 0 bytes, original chunk may have been truncated"); break; } nb_read += current_read; } TRACE("buffer filled"); errno = 0; /* write buf to dst file */ if(nb_read > 0 && fwrite(data, nb_read, 1, dst) != 1) { GSETERROR(error, "An error occured while writing data in destination file: %s", strerror(errno)); goto end; } if (data) { g_free(data); data = NULL; } if (nb_read > 0) total_read += nb_read; else break; } if(!comp_ctx->integrity_checker(cp_chunk)) { GSETERROR(error, "Seems there is an error in decompression, invalid checksum\n"); goto end; } status = 1; end: if(dst) { if(fclose(dst) != 0) WARN("Failed to fclose destination file"); dst = NULL; } if(status == 1) { if(preserve) { /* Need to set old file info in new file */ TRACE("Updating Access / Modify / Change informations"); struct utimbuf* ut = NULL; ut = g_malloc0(sizeof(struct utimbuf)); ut->actime = buf->st_atime; ut->modtime = buf->st_mtime; if (0 > chown(tmp_path, buf->st_uid, buf->st_gid)) { GSETERROR(error, "chown error: (%d) %s", errno, strerror(errno)); status = 0; } if(utime(tmp_path, ut) != 0) { GSETERROR(error, "Failed to set correct access time to new file"); status = 0; } if(ut) g_free(ut); if(status == 1) { if(rename(tmp_path, path) != 0) { GSETERROR(error, "Failed to rename tmp file"); status = 0; } } else if (keep_pending) { INFO("Temporary file kept: %s", tmp_path); } else { /* remove tmp file */ DEBUG("Removing failed file"); if(remove(tmp_path) != 0) WARN("Failed to remove tmp file [%s]", tmp_path); } } else { DEBUG("Renaming pending file\n"); if(rename(tmp_path, path) != 0) { GSETERROR(error, "Failed to rename tmp file"); status = 0; } } } else if (keep_pending) { INFO("Temporary file kept: %s", tmp_path); } else { /* remove tmp file */ DEBUG("Removing pending file\n"); if(remove(tmp_path) != 0) WARN("Failed to remove tmp file [%s]", tmp_path); } if(compress_opt) g_hash_table_destroy(compress_opt); if(buf) g_free(buf); if(data) g_free(data); if(tmp_path) g_free(tmp_path); return status; }
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; }
gint accept_add_local (ACCEPT_POOL ap, const gchar *l, GError **err) { struct working_parameter_s wrkParam; struct sockaddr_un sun; int srv = -1; if (!l || !(*l)) { GSETERROR(err,"invalid parameter"); goto errorLabel; } /*parse the URL*/ init_socket_options_defaults( l, &wrkParam ); parse_socket_options( &wrkParam ); /*try to stat the file*/ if (-1 == check_socket_is_absent( &wrkParam, err )) { GSETERROR(err,"A socket seems already present at [%s]", wrkParam.path.ptr); } /*open and bind the socket*/ if (-1==(srv=socket(PF_UNIX, SOCK_STREAM, 0))) { GSETERROR(err,"Cannot open a new socket PF_UNIX : %s", strerror(errno)); goto errorLabel; } if (!sock_set_reuseaddr(srv, TRUE)) { GSETERROR(err,"Cannot set SO_REUSEADDR on %d [%s] (%s)", srv, l, strerror(errno)); goto errorLabel; } fcntl(srv, F_SETFL, O_NONBLOCK|fcntl(srv, F_GETFL)); sun.sun_family = PF_LOCAL; strncpy(sun.sun_path, wrkParam.path.ptr, sizeof(sun.sun_path)); if (-1==bind (srv, (struct sockaddr*) &sun, sizeof(struct sockaddr_un))) { GSETERROR(err,"cannot bind srv=%d to %s (%s)", srv, l, strerror(errno)); goto errorLabel; } if (-1==listen (srv,AP_BACKLOG)) { GSETERROR(err,"cannot listen to inbound connections : %s", strerror(errno)); goto errorLabel; } if (!accept_add_any(ap,srv,err)) { GSETERROR(err,"Cannot monitor the local server"); goto errorLabel; } /*change socket rights*/ if (0 != chmod(wrkParam.path.ptr,wrkParam.mode)) { int errsav = errno; ERROR("Failed to set mode [%o] on UNIX socket [%s] : %s", wrkParam.mode, wrkParam.path.ptr, strerror(errsav)); SRV_SEND_WARNING("server","UNIX socket might be not accessible : failed to set mode [%o] on UNIX socket [%s] (%s)", wrkParam.mode, wrkParam.path.ptr, strerror(errsav)); } INFO("socket srv=%d %s now monitored", srv, _get_family_name(FAMILY(&sun))); return 1; errorLabel: if (srv>=0) metautils_pclose(&srv); return 0; }
static struct network_client_s * _endpoint_manage_event(struct network_server_s *srv, struct endpoint_s *e) { int fd; struct sockaddr_storage ss; socklen_t ss_len; retry: memset(&ss, 0, sizeof(ss)); ss_len = sizeof(ss); fd = accept_nonblock(e->fd, (struct sockaddr*)&ss, &ss_len); if (0 > fd) { if (errno == EINTR) goto retry; if (errno != EAGAIN && errno != EWOULDBLOCK) GRID_WARN("fd=%d ACCEPT error (%d %s)", e->fd, errno, strerror(errno)); return NULL; } switch (e->flags) { case NETSERVER_THROUGHPUT: sock_set_cork(fd, TRUE); break; case NETSERVER_LATENCY: sock_set_linger_default(fd); sock_set_nodelay(fd, TRUE); sock_set_tcpquickack(fd, TRUE); break; default: break; } struct network_client_s *clt = SLICE_NEW0(struct network_client_s); if (NULL == clt) { metautils_pclose(&fd); _cnx_notify_close(srv); return NULL; } switch (_cnx_notify_accept(srv)) { case EXCESS_SOFT: clt->current_error = NEWERROR(CODE_UNAVAILABLE, "Server overloaded."); case EXCESS_NONE: break; case EXCESS_HARD: metautils_pclose(&fd); _cnx_notify_close(srv); return NULL; } clt->main_stats = srv->stats; clt->server = srv; clt->fd = fd; grid_sockaddr_to_string((struct sockaddr*)&ss, clt->peer_name, sizeof(clt->peer_name)); _client_sock_name(fd, clt->local_name, sizeof(clt->local_name)); clt->time.cnx = network_server_bogonow(srv); clt->events = CLT_READ; clt->input.first = clt->input.last = NULL; clt->output.first = clt->output.last = NULL; if (e->factory_hook) e->factory_hook(e->factory_udata, clt); return clt; }
int compress_chunk(const gchar* path, const gchar* algo, const gint64 blocksize, gboolean preserve, GError ** error) { GError *local_error = NULL; int status = 0; gchar *tmp_path = NULL; gulong tmp_len; guint32 compressed_size = 0; struct compression_ctx_s* comp_ctx = NULL; struct stat *stat_buf = NULL; guint8* buf = NULL; gsize nb_read; gsize nb_write; GByteArray *gba = NULL; gulong checksum = 0; FILE *src = NULL; FILE *dst = NULL; /* Sanity check */ if(!path || ! algo) { GSETERROR(error, "Invalid parameter %p\n", path); return status; } if(!check_uncompressed_chunk(path, &local_error)) { if(local_error) { GSETERROR(error, "Chunk check failed :\n%s", local_error->message); g_clear_error(&local_error); } else GSETERROR(error, "Chunk check failed : no error\n"); return status; } tmp_len = strlen(path) +sizeof(".pending"); tmp_path = g_malloc0(tmp_len); g_snprintf(tmp_path, tmp_len, "%s.pending", path); comp_ctx = g_malloc0(sizeof(struct compression_ctx_s)); if(!init_compression_ctx(comp_ctx, algo)) { GSETERROR(error, "Failed to init compression context\n"); goto end; } if(!comp_ctx->checksum_initiator(&checksum)) { GSETERROR(error, "Failed to init compression checksum\n"); goto end; } stat_buf = g_malloc0(sizeof(struct stat)); if(stat(tmp_path, stat_buf) != -1) { GSETERROR (error, "stat() success on pending file, cannot process : chunk busy\n"); goto end; } do { int fd; if((fd = open(tmp_path, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1) { GSETERROR(error, "Failed to create pending chunk file (%s)\n", strerror(errno)); goto end; } metautils_pclose(&fd); } while (0); if(!copy_fattr(path, tmp_path, &local_error)) { if(local_error) { GSETERROR(error, "Failed to copy extended attributes to destination file:\n%s",local_error->message); g_clear_error(&local_error); } else GSETERROR(error, "Failed to copy extended attributes to destination file\n"); goto end; } DEBUG("Extended attributes copied from src to dst\n"); if(!set_compress_attr(tmp_path, algo, blocksize, &local_error)) { if(local_error) { GSETERROR(error, "Error while adding compression attibutes :\n %s", local_error->message); g_clear_error(&local_error); } goto end; } DEBUG("Compression extended attributes successfully added\n"); src = fopen(path, "r"); dst = fopen(tmp_path, "w"); guint32 bsize32 = blocksize; if(comp_ctx->header_writer(dst, bsize32, &checksum, &compressed_size) != 0) { GSETERROR(error, "Failed to compress source file\n"); goto end; } int src_fd = fileno(src); gsize bsize = blocksize; buf = g_malloc0(blocksize); while(1) { nb_read = 0; nb_read = read(src_fd, buf, bsize); if(nb_read != bsize) { /* check if we hit eof */ if(!feof(src) && ferror(src)) { GSETERROR(error, "An error occured while reading data from source file\n"); goto end; } else { if(nb_read > 0) { gba = g_byte_array_new(); /* process data */ if(0 != comp_ctx->data_compressor(buf, nb_read, gba, &checksum)) { GSETERROR(error, "Error while compressing data\n"); goto end; } /* write compressed data */ nb_write = 0; if ((nb_write = fwrite(gba->data, gba->len, 1, dst)) != 1) { GSETERROR(error, "An error occured while writing data in destination file\n"); goto end; } compressed_size+=gba->len; if(gba) { g_byte_array_free(gba, TRUE); gba = NULL; } } break; } } else { gba = g_byte_array_new(); /* process data */ if(0 != comp_ctx->data_compressor(buf, nb_read, gba, &checksum)) { GSETERROR(error, "Error while compressing data\n"); goto end; } /* write compressed data */ nb_write = 0; if ((nb_write = fwrite(gba->data, gba->len, 1, dst)) != 1) { GSETERROR(error, "An error occured while writing data in destination file\n"); goto end; } compressed_size+=gba->len; if(gba) { g_byte_array_free(gba, TRUE); gba = NULL; } } } DEBUG("Chunk compressed"); if(comp_ctx->eof_writer(dst, checksum, &compressed_size) != 0) { GSETERROR(error, "Failed to write compressed file EOF marker and checksum\n"); goto end; } if(!set_chunk_compressed_size_in_attr(tmp_path, error, compressed_size)) { GSETERROR(error, "Failed to set compression information in extended attributes\n"); goto end; } DEBUG("Compression footers successfully wrote"); status = 1; end: if(src) { if(fclose(src) != 0) WARN("Failed to fclose source file"); src = NULL; } if(dst) { if(fclose(dst) != 0) WARN("Failed to fclose destination file"); dst = NULL; } if(status == 1) { /* TODO: stat old file, rename, paste stat*/ if(preserve) { /* Need to set old file info in new file */ TRACE("Renaming and setting good informations to new file..."); if(stat_buf) g_free(stat_buf); stat_buf = g_malloc0(sizeof(struct stat)); if(stat(path, stat_buf) == -1) { GSETERROR (error, "Failed to stat old file, cannot keep old file information, abort\n"); /* remove tmp file */ DEBUG("Removing failed file"); if(remove(tmp_path) != 0) WARN("Failed to remove tmp file [%s]", tmp_path); status = 0; } else { TRACE("Updating Access / Modify / Change informations"); struct utimbuf* ut = NULL; ut = g_malloc0(sizeof(struct utimbuf)); ut->actime = stat_buf->st_atime; ut->modtime = stat_buf->st_mtime; if (0 > chown(tmp_path, stat_buf->st_uid, stat_buf->st_gid)) { GSETERROR(error, "chown error: (%d) %s", errno, strerror(errno)); status = 0; } if(utime(tmp_path, ut) != 0) { GSETERROR(error, "Failed to set correct access time to new file"); status = 0; } if(ut) g_free(ut); if(status == 1) { if(rename(tmp_path, path) != 0) { GSETERROR(error, "Failed to rename tmp file"); status = 0; } } else { /* remove tmp file */ DEBUG("Removing failed file"); if(remove(tmp_path) != 0) WARN("Failed to remove tmp file [%s]", tmp_path); } } } else { TRACE("Renaming pending file..."); if(rename(tmp_path, path) != 0) { GSETERROR(error, "Failed to rename tmp file"); status = 0; } TRACE("Renaming done"); } } else { /* remove tmp file */ DEBUG("Removing failed file"); if(remove(tmp_path) != 0) WARN("Failed to remove tmp file [%s]", tmp_path); } if(stat_buf) g_free(stat_buf); if(buf) g_free(buf); if(gba) g_byte_array_free(gba, TRUE); if(tmp_path) g_free(tmp_path); return status; }
static GError * _client_manage_reply(struct gridd_client_s *client, MESSAGE reply) { GError *err; guint status = 0; gchar *message = NULL; if (NULL != (err = metaXClient_reply_simple(reply, &status, &message))) { g_prefix_error (&err, "reply: "); return err; } STRING_STACKIFY(message); if (CODE_IS_NETWORK_ERROR(status)) { err = NEWERROR(status, "net error: %s", message); metautils_pclose(&(client->fd)); client->step = STATUS_FAILED; return err; } if (status == CODE_TEMPORARY) { client->step = REP_READING_SIZE; return NULL; } if (CODE_IS_OK(status)) { client->step = (status==CODE_FINAL_OK) ? STATUS_OK : REP_READING_SIZE; if (client->step == STATUS_OK) { if (!client->keepalive) metautils_pclose(&(client->fd)); } if (client->on_reply) { if (!client->on_reply(client->ctx, reply)) return NEWERROR(CODE_INTERNAL_ERROR, "Handler error"); } return NULL; } if (status == CODE_REDIRECT && !client->forbid_redirect) { /* Reset the context */ _client_reset_reply(client); _client_reset_cnx(client); client->sent_bytes = 0; if ((++ client->nb_redirects) > 3) return NEWERROR(CODE_TOOMANY_REDIRECT, "Too many redirections"); /* Replace the URL */ g_strlcpy(client->url, message, URL_MAXLEN); if (NULL != (err = _client_connect(client))) g_prefix_error(&err, "Redirection error: Connect error: "); return err; } /* all other are considered errors */ if (status != CODE_REDIRECT) err = NEWERROR(status, "Request error: %s", message); else err = NEWERROR(status, "%s", message); if (!client->keepalive) _client_reset_cnx(client); _client_reset_reply(client); return err; }
static GError * _client_manage_reply(struct gridd_client_s *client, MESSAGE reply) { GError *err; gint status = 0; gchar *message = NULL; if (!metaXClient_reply_simple(reply, &status, &message, NULL)) return NEWERROR(500, "Invalid reply"); switch (status / 100) { case 0: err = NEWERROR(status, "net error: %s", message); g_free(message); metautils_pclose(&(client->fd)); client->step = STATUS_FAILED; return err; case 1: /* Informational reply : */ g_get_current_time(&(client->tv_step)); client->step = REP_READING_SIZE; g_free(message); return NULL; case 2: g_get_current_time(&(client->tv_step)); client->step = (status==200) ? STATUS_OK : REP_READING_SIZE; if (client->step == STATUS_OK) { if (!client->keepalive) metautils_pclose(&(client->fd)); } g_free(message); if (client->on_reply) { if (!client->on_reply(client->ctx, reply)) return NEWERROR(500, "Handler error"); } return NULL; case 3: /* redirection */ if (status == CODE_REDIRECT) { /* Reset the context */ _client_reset_reply(client); _client_reset_cnx(client); client->sent_bytes = 0; if ((++ client->nb_redirects) > 7) { g_free(message); return NEWERROR(CODE_TOOMANY_REDIRECT, "Too many redirections"); } /* Save the current URL to avoid looping, and check * for a potential loop */ g_string_append_c(client->past_url, '|'); g_string_append(client->past_url, client->url); if (_client_looped(client, message)) { g_free(message); return NEWERROR(CODE_LOOP_REDIRECT, "Looping on redirections"); } /* Replace the URL */ memset(client->url, 0, sizeof(client->url)); g_strlcpy(client->url, message, sizeof(client->url)-1); if (NULL != (err = _client_connect(client))) { g_free(message); g_prefix_error(&err, "Redirection error: Connect error: "); return err; } g_free(message); return NULL; } /* FALLTHROUGH */ default: /* all other are considered errors */ err = NEWERROR(status, "Request error: %s", message); g_free(message); if (!client->keepalive) _client_reset_cnx(client); _client_reset_reply(client); return err; } }
static void parse_output(const gchar *cmd, service_info_t *si) { int fd; FILE *stream_in; gchar line[1024]; gchar cmd_with_args[4096] = {0,0,0}; g_snprintf(cmd_with_args, sizeof(cmd_with_args), "%s %s", cmd, svc_id); INFO("Executing [%s]", cmd_with_args); if (0 > (fd = command_get_pipe(cmd_with_args))) { WARN("Exec failed: %s", strerror(errno)); return; } if (!(stream_in = fdopen(fd, "r"))) { WARN("fdopen failed: %s", strerror(errno)); metautils_pclose(&fd); return; } while (!feof(stream_in) && !ferror(stream_in)) { GMatchInfo *mi = NULL; bzero(line, sizeof(line)); if (!fgets(line, sizeof(line), stream_in)) { break; } /* chomp the line */ my_chomp(line); if (!g_regex_match(regex_tag, line, 0, &mi)) { NOTICE("Unrecognized pattern for output line [%s]", line); } else { struct service_tag_s *tag; gchar *str_type, *str_name, *str_value; str_name = g_match_info_fetch(mi, 1); str_type = g_match_info_fetch(mi, 2); str_value = g_match_info_fetch(mi, 4); if (!g_ascii_strcasecmp(str_type, "tag")) { tag = service_info_ensure_tag(si->tags, str_name); service_tag_set_value_string(tag, str_value); } else if (!g_ascii_strcasecmp(str_type, "stat")) { gdouble dval; dval = g_ascii_strtod(str_value, NULL); tag = service_info_ensure_tag(si->tags, str_name); service_tag_set_value_float(tag, dval); } g_free(str_value); g_free(str_type); g_free(str_name); } g_match_info_free(mi); } fclose(stream_in); }