Пример #1
0
Файл: os.c Проект: fachat/XD2031
int os_stdin_has_data(void) {
	fd_set rfds;
	struct timeval tv;
	int res;

	// Watch stdin (fd 0) to see when it has input
	FD_ZERO(&rfds);
	FD_SET(0, &rfds);

	// Don't block
	tv.tv_sec = 0;
	tv.tv_usec = 0;

	res = select(1, &rfds, NULL, NULL, &tv);
	// Don't rely on the value of tv now!

	if (res == -1) {
		log_error("select(): (%d) %s\n", os_errno(), os_strerror(os_errno()));
		return 0;
	} else if(res) {
		// data available in stdin
		return 1;
	}

	// no data available
	return 0;
}
Пример #2
0
void ls_switch_file( ChannelLog *cl )
{
	static char tmbuf[MAXPATH];
	static char newfname[MAXPATH];
	static char oldfname[MAXPATH];
	int res;

	/* no need to switch, its not opened */
	if( cl->logfile == NULL  ) return;		
	ls_close_log( cl );
	/* check if the target directory exists */
	if( os_create_dir( LogServ.savedir ) != NS_SUCCESS )
	{
		return;
	}
	os_strftime( tmbuf, MAXPATH, "%d%m%Y%H%M%S", os_localtime( &me.now ) );
	ircsnprintf( newfname, MAXPATH, "%s/%s-%s.log", LogServ.savedir, cl->filename, tmbuf );
	ircsnprintf( oldfname, MAXPATH, "%s/%s.log", LogServ.logdir, cl->filename );
	res = os_rename( oldfname, newfname );
	if( res != 0 ) {
		nlog( LOG_CRITICAL, "Couldn't rename file %s: %s", oldfname, os_strerror() );
		return;
	}	
	nlog( LOG_NORMAL, "Switched Logfile for %s from %s to %s", cl->channame, oldfname, newfname );
}
Пример #3
0
exa_select_handle_t *exa_select_new_handle(void)
{
    exa_select_handle_t *h = os_malloc(sizeof(exa_select_handle_t));
    EXA_ASSERT(h != NULL);
#if WIN32
    h->magic = EXA_SELECT_MAGIC;
#else
    h->fd = open(EXACOMMON_MODULE_PATH, O_RDWR);
    EXA_ASSERT_VERBOSE(h->fd >= 0, "Cannot bind to exa_common module: %s (%d)",
                       os_strerror(errno), -errno);

    EXA_ASSERT_VERBOSE(ioctl(h->fd, EXA_SELECT_MAL) != -1,
                       "Cannot register to exa_common module: %s (%d)",
                       os_strerror(errno), -errno);
#endif
    return h;
}
Пример #4
0
/* this function is called when an error is found during directory traversal */
static void process_error(struct a6o_scan *scan, const char *full_path, int entry_errno)
{
	struct a6o_report report;

	a6o_report_init(&report, scan->scan_id, full_path, REPORT_PROGRESS_UNKNOWN);

	a6o_log(ARMADITO_LOG_LIB, ARMADITO_LOG_LEVEL_WARNING, "error processing %s (error %s)", full_path, os_strerror(entry_errno));

	report.status = ARMADITO_IERROR;
	report.mod_report = os_strdup(os_strerror(entry_errno));
	a6o_scan_call_callbacks(scan, &report);

	a6o_report_destroy(&report);
}
Пример #5
0
static int ls_open_log( ChannelLog *cl )
{
	static char fname[MAXPATH];

	/* first, make sure the logdir dir exists */
	if( os_create_dir( LogServ.logdir ) != NS_SUCCESS )
	{
		return NS_FAILURE;
	}
	/* copy name to the filename holder( in case of invalid paths ) */
	strlcpy( cl->filename, cl->channame, MAXPATH );
	ircsnprintf( fname, MAXPATH, "%s/%s.log", LogServ.logdir, make_safe_filename( cl->filename ) );
	/* open the file */
	cl->logfile = os_fopen( fname, "a" );
	if( cl->logfile == NULL )
	{
		nlog( LOG_CRITICAL, "Could not open %s for appending: %s", cl->filename, os_strerror() );
		return NS_FAILURE;
	}
	dlog( DEBUG1, "Opened %s for appending", cl->filename );
	cl->ts_open = me.now;
	logging_funcs[LogServ.logtype][LGSMSG_START]( cl, NULL );
	return NS_SUCCESS;
}
Пример #6
0
int
mdns_strerror(int r, char *buf, size_t n)
{
        return os_strerror(r, buf, n);
}
Пример #7
0
/*
 * thread responsible for receiving data for a client or a server
 * note when we add client, this client is effectively added in the receive queue
 * only few second later due to the select timeout of 3 seconds
 * and there are the same problem for the deleteion of a client
 */
static void algopr_receive_thread(void *unused)
{
    struct pending_request pending_requests[EXA_MAX_NODES_NUMBER];
    exa_select_handle_t *sh = exa_select_new_handle();
    int i;
    int ret;
    payload_t *payload = NULL;
    struct nbd_root_list root_list_recv;

    /* FIXME: handle the case when we have more than 1024 open file (limit of fd_set) */
    fd_set fds;

    exalog_as(EXAMSG_ISCSI_ID);

    nbd_init_root(EXA_MAX_NODES_NUMBER, sizeof(payload_t), &root_list_recv);

    for (i = 0; i < EXA_MAX_NODES_NUMBER; i++)
        request_reset(&pending_requests[i]);

    while (algopr_run)
    {
	int nfds = 0;
        FD_ZERO(&fds);
        /* if one node is added or deleted, this deletion or addition are
           effective after this */
        os_thread_mutex_lock(&peers_lock);
        for (i = 0; i < EXA_MAX_NODES_NUMBER; i++)
        {
            int fd_act = __get_peer_socket(i);
            if (fd_act < 0)
            {
                payload_t *temp_payload;
                temp_payload = request_reset(&pending_requests[i]);
                if (temp_payload != NULL)
                {
                    if (pending_requests[i].big_buffer)
                        nbd_list_post(&eth.root_list_big_recv.free,
                                      temp_payload->buffer, -1);

                    nbd_list_post(&root_list_recv.free, temp_payload, -1);
                }
                temp_payload = NULL;
                continue;
            }

            FD_SET(fd_act, &fds);
	    nfds = fd_act > nfds ? fd_act : nfds;
        }
        os_thread_mutex_unlock(&peers_lock);

        ret = exa_select_in(sh, nfds + 1, &fds);
        if (ret != 0 && ret != -EFAULT)
            exalog_error("Select upon receive failed: %s (%d)",
                         os_strerror(-ret), ret);

        os_thread_mutex_lock(&peers_lock);
        for (i = 0; i < EXA_MAX_NODES_NUMBER; i++)
        {
            struct pending_request *req;
            int fd_act;

            fd_act = __get_peer_socket(i);
            if (fd_act < 0 || !FD_ISSET(fd_act, &fds))
                continue;

            req = &pending_requests[i];
            /* WARNING payload is kept from an iteration of while loop to
             * another, so the variable MUST be global. */
            /* FIXME Remove the nbdlist which is useless as we already know
             * that we NEED EXA_MAX_NODES_NUMBER payload_t elements to be able
             * to receive simultaneously from EXA_MAX_NODES_NUMBER nodes
             * FIXME the LISTWAIT flag below is WRONG because waiting here
             * would mean deadlock... hopefully there are enough elements, and
             * we never wait.... */
            if (payload == NULL)
            {
                payload = nbd_list_remove(&root_list_recv.free, NULL, LISTWAIT);
                EXA_ASSERT(payload != NULL);
            }
            if (request_init_transfer(payload, req) == 1)
                payload = NULL;

            ret = request_receive(fd_act, req);
            if (ret == DATA_TRANSFER_NEED_BIG_BUFFER)
            {
                req->payload->buffer = nbd_list_remove(&eth.root_list_big_recv.free,
                                                       NULL, LISTWAIT);
                EXA_ASSERT(req->payload->buffer != NULL);

                req->big_buffer = true;

                /* here we just continue because it is forbidden to call
                 * request_receive without passing into select (as sockets are
                 * blocking, we may remain blocked on the recv of nothing) */
                continue;
            }

            if (ret == DATA_TRANSFER_PENDING)
                continue;

            if (ret == DATA_TRANSFER_ERROR)
            {
                payload_t *temp_payload = request_reset(req);

                if (req->big_buffer)
                    nbd_list_post(&eth.root_list_big_recv.free,
                                  temp_payload->buffer, -1);

                nbd_list_post(&root_list_recv.free, temp_payload, -1);

                __disconnect_from_peer(i);

                if (!suspended)
                    exalog_warning("Failed receiving from peer %" PRInodeid
                                  " (socket %d): transfer error.", i, fd_act);
                continue;
            }

            if (ret == DATA_TRANSFER_COMPLETE)
            {
                payload_t *_payload = request_reset(req);

                /* update data network checking data */
                algopr_new_msg(_payload->payload, _payload->size1,
                               _payload->buffer,  _payload->size2);
                nbd_list_post(&root_list_recv.free, _payload, -1);
            }
        }
        os_thread_mutex_unlock(&peers_lock);
    }

    nbd_close_root(&root_list_recv);
    exa_select_delete_handle(sh);
}
Пример #8
0
static int __connect_to_peer(exa_nodeid_t node_id)
{
    peer_t *peer;
    struct sockaddr_in this_node_addr;
    struct sockaddr_in serv_addr;
    struct in_addr inaddr;
    int sock = -1;
    int err = EXA_SUCCESS;
    int r;

    peer = &peers[node_id];

    exalog_debug("connecting to peer %"PRInodeid" '%s'", node_id, peer->ip_addr);

    EXA_ASSERT(peer->ip_addr[0] != '\0');
    EXA_ASSERT(peer->sock == -1);

    r = os_inet_aton(peer->ip_addr, &inaddr);
    if (r == 0)
    {
        exalog_error("Invalid IP '%s' for node %"PRInodeid, peer->ip_addr, node_id);
        err = -EXA_ERR_CREATE_SOCKET;
        goto done;
    }

    r = os_socket(PF_INET, SOCK_STREAM, 0);
    if (r < 0)
    {
        exalog_error("Failed creating socket: %s (%d)", os_strerror(-r), r);
        err = -EXA_ERR_CREATE_SOCKET;
        goto done;
    }
    sock = r;

    /* Bind the socket. Otherwise the system would be free to use whichever
       interface it pleases, which may not match the IP address this node is
       known as on other nodes participating in the PR. */
    this_node_addr.sin_family = AF_INET;
    os_inet_aton(peers[this_node_id].ip_addr, &this_node_addr.sin_addr);
    this_node_addr.sin_port = htons(0); /* let the system choose */
    r = os_bind(sock, (struct sockaddr *)&this_node_addr, sizeof(this_node_addr));
    if (r < 0)
    {
        exalog_error("Failed binding socket %d to %s: %s (%d)", sock,
                     peers[this_node_id].ip_addr, os_strerror(-r), r);
        err = -EXA_ERR_CREATE_SOCKET;
        goto done;
    }

    os_sock_set_timeouts(sock, 4000);

    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inaddr.s_addr;
    serv_addr.sin_port = htons(algopr_network_port);
    r = os_connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    if (r < 0)
    {
        exalog_error("Cannot connect to node %d (IP '%s'): %s (%d)",
                     node_id, peer->ip_addr, os_strerror(-r), r);
        err = -NBD_ERR_SERVER_REFUSED_CONNECTION;
        goto done;
    }

    os_sock_set_timeouts(sock, 0);
    internal_setsock_opt(sock, SOCK_FLAGS);

    peer->sock = sock;

done:
    if (err != EXA_SUCCESS && sock != -1)
        __close_socket(sock);

    return err;
}
Пример #9
0
/**
 * Return a new allocated array of list of paths allowed to be used on the
 * node or NULL if file is not found or an error occured while reading.
 *
 * WARNING this function allocates memory, and the returned buffer
 * MUST be freed by caller with os_free.
 *
 * @param[in:out] err_desc   an error descriptor for output.
 *
 * @return a rdev_path_t array of NBMAX_DISKS_PER_NODE elements.
 */
static rdev_path_t *rdev_read_disk_conf_file(cl_error_desc_t *err_desc)
{
    /* file is opened read only because the code in here is not supposed to
     * modify it. The only way to modify the RDEV_FILE is via an administative
     * action (edit the file) */
    FILE *disk_list;
    rdev_path_t *disk_array = NULL, *it = NULL;
    char disk_conf_file[OS_PATH_MAX];
    char line[EXA_MAXSIZE_DEVPATH + 2]; /* likely ends '\n\0' */
    const char *conf_dir = NULL;

    OS_ASSERT(err_desc != NULL);

    /* note that conf_dir is afforded to end with FILE_SEP */
    conf_dir = exa_env_nodeconfdir();
    if (conf_dir == NULL)
    {
	set_error(err_desc, -EXA_ERR_BAD_INSTALL,
		  "Environment key 'EXANODES_NODE_CONF_DIR' not set.");
	return NULL;
    }

    if (os_snprintf(disk_conf_file, sizeof(disk_conf_file), "%s" RDEV_FILE, conf_dir)
        >= sizeof(disk_conf_file))
    {
	set_error(err_desc, -EXA_ERR_BAD_INSTALL,
		  "Environment key 'EXANODES_NODE_CONF_DIR' too long.");
	return NULL;
    }

    disk_list = fopen(disk_conf_file, "r");
    if (disk_list == NULL)
    {
	/* A non-existent file is not an error */
	if (errno == ENOENT)
	    set_success(err_desc);
        else
            set_error(err_desc, -errno, "File " RDEV_FILE " cannot be read: %s (%d)",
                      os_strerror(errno), -errno);
        return NULL;
    }

    /* prepare array */
    disk_array = os_malloc(sizeof(rdev_path_t) * NBMAX_DISKS_PER_NODE);

    for (it = disk_array; it < disk_array + NBMAX_DISKS_PER_NODE; it++)
	it->path[0] = '\0';

    for (it = disk_array; it < disk_array + NBMAX_DISKS_PER_NODE; it++)
    {
	char *ptr = fgets(line, sizeof(line), disk_list);
        size_t len;

	if (ptr == NULL)
	    break;

	/* remove final '\n'*/
        len = strlen(line);
	if (line[len - 1] == '\n')
	    line[len - 1] = '\0';

        os_str_trim_right(line);

	/* FIXME no check if disk name is truncated here */
	os_strlcpy(it->path, line, EXA_MAXSIZE_DEVPATH + 1);
    }

    /* too many lines in the file -> error */
    if (it == disk_array + NBMAX_DISKS_PER_NODE
	    && fgets(line, sizeof(line), disk_list) != NULL)
    {
	os_free(disk_array);
	fclose(disk_list);

	set_error(err_desc, -EINVAL, "Too many entries in " RDEV_FILE ".");
	return NULL;
    }

    fclose(disk_list);

    set_success(err_desc);

    return disk_array;
}