Esempio n. 1
0
/**
 * Parses \<numaddr_range\> token of the syntax.
 *
 * \retval 1 if \a str parses to \<number\> | \<expr_list\>
 * \retval 0 otherwise
 */
static int
num_parse(char *str, int len,
          cfs_list_t *list, unsigned min, unsigned max)
{
    __u32 num;
    struct lstr src;
    struct numaddr_range *numaddr;

    src.ls_str = str;
    src.ls_len = len;

    LIBCFS_ALLOC(numaddr, sizeof(struct numaddr_range));
    if (numaddr == NULL)
        return 0;
    cfs_list_add_tail(&numaddr->nar_link, list);
    CFS_INIT_LIST_HEAD(&numaddr->nar_range_exprs);

    if (libcfs_str2num_check(src.ls_str, src.ls_len, &num, min, max)) {
        /* <number> */
        struct range_expr *expr;

        LIBCFS_ALLOC(expr, sizeof(struct range_expr));
        if (expr == NULL)
            return 0;

        expr->re_lo = expr->re_hi = num;
        expr->re_stride = 1;
        cfs_list_add_tail(&expr->re_link, &numaddr->nar_range_exprs);
        return 1;
    }

    return parse_expr_list(&src, &numaddr->nar_range_exprs, min, max);
}
Esempio n. 2
0
int
lst_batch_add_ioctl(lstio_batch_add_args_t *args)
{
        int             rc;
        char           *name;

        if (args->lstio_bat_key != console_session.ses_key)
                return -EACCES;

        if (args->lstio_bat_namep == NULL ||
            args->lstio_bat_nmlen <= 0 ||
            args->lstio_bat_nmlen > LST_NAME_SIZE)
                return -EINVAL;

        LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
        if (name == NULL)
                return -ENOMEM;

        if (cfs_copy_from_user(name,
                               args->lstio_bat_namep,
                               args->lstio_bat_nmlen)) {
                LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
                return -EFAULT;
        }

        name[args->lstio_bat_nmlen] = 0;

        rc = lstcon_batch_add(name);

        LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);

        return rc;
}
Esempio n. 3
0
static int
lnet_selftest_init(void)
{
	int nscheds;
	int rc;
	int i;

	rc = cfs_wi_sched_create("lst_s", lnet_cpt_table(), CFS_CPT_ANY,
				 1, &lst_sched_serial);
	if (rc != 0) {
		CERROR("Failed to create serial WI scheduler for LST\n");
		return rc;
	}
	lst_init_step = LST_INIT_WI_SERIAL;

	nscheds = cfs_cpt_number(lnet_cpt_table());
	LIBCFS_ALLOC(lst_sched_test, sizeof(lst_sched_test[0]) * nscheds);
	if (lst_sched_test == NULL)
		goto error;

	lst_init_step = LST_INIT_WI_TEST;
	for (i = 0; i < nscheds; i++) {
		int nthrs = cfs_cpt_weight(lnet_cpt_table(), i);

		/* reserve at least one CPU for LND */
		nthrs = max(nthrs - 1, 1);
		rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i,
					 nthrs, &lst_sched_test[i]);
		if (rc != 0) {
			CERROR("Failed to create CPT affinity WI scheduler %d for LST\n",
			       i);
			goto error;
		}
	}

	rc = srpc_startup();
	if (rc != 0) {
		CERROR("LST can't startup rpc\n");
		goto error;
	}
	lst_init_step = LST_INIT_RPC;

	rc = sfw_startup();
	if (rc != 0) {
		CERROR("LST can't startup framework\n");
		goto error;
	}
	lst_init_step = LST_INIT_FW;

	rc = lstcon_console_init();
	if (rc != 0) {
		CERROR("LST can't startup console\n");
		goto error;
	}
	lst_init_step = LST_INIT_CONSOLE;
	return 0;
error:
	lnet_selftest_fini();
	return rc;
}
Esempio n. 4
0
static int
lst_batch_run_ioctl(lstio_batch_run_args_t *args)
{
	int rc;
	char *name;

	if (args->lstio_bat_key != console_session.ses_key)
		return -EACCES;

	if (!args->lstio_bat_namep ||
	    args->lstio_bat_nmlen <= 0 ||
	    args->lstio_bat_nmlen > LST_NAME_SIZE)
		return -EINVAL;

	LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
	if (!name)
		return -ENOMEM;

	if (copy_from_user(name, args->lstio_bat_namep,
			   args->lstio_bat_nmlen)) {
		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
		return -EFAULT;
	}

	name[args->lstio_bat_nmlen] = 0;

	rc = lstcon_batch_run(name, args->lstio_bat_timeout,
			      args->lstio_bat_resultp);

	LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);

	return rc;
}
Esempio n. 5
0
static int
lst_group_add_ioctl(struct lstio_group_add_args *args)
{
        char           *name;
        int             rc;

        if (args->lstio_grp_key != console_session.ses_key)
                return -EACCES;

        if (args->lstio_grp_namep == NULL||
	    args->lstio_grp_nmlen <= 0 ||
            args->lstio_grp_nmlen > LST_NAME_SIZE)
                return -EINVAL;

        LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
        if (name == NULL)
                return -ENOMEM;

	if (copy_from_user(name, args->lstio_grp_namep,
			   args->lstio_grp_nmlen)) {
                LIBCFS_FREE(name, args->lstio_grp_nmlen);
                return -EFAULT;
        }

        name[args->lstio_grp_nmlen] = 0;

        rc = lstcon_group_add(name);

        LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);

        return rc;
}
Esempio n. 6
0
static int
lst_batch_stop_ioctl(struct lstio_batch_stop_args *args)
{
        int             rc;
        char           *name;

        if (args->lstio_bat_key != console_session.ses_key)
                return -EACCES;

        if (args->lstio_bat_resultp == NULL ||
            args->lstio_bat_namep == NULL ||
            args->lstio_bat_nmlen <= 0 ||
            args->lstio_bat_nmlen > LST_NAME_SIZE)
                return -EINVAL;

        LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
        if (name == NULL)
                return -ENOMEM;

	if (copy_from_user(name, args->lstio_bat_namep,
			   args->lstio_bat_nmlen)) {
		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
		return -EFAULT;
	}

        name[args->lstio_bat_nmlen] = 0;

        rc = lstcon_batch_stop(name, args->lstio_bat_force,
                               args->lstio_bat_resultp);

        LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);

        return rc;
}
Esempio n. 7
0
static int
lst_session_new_ioctl(struct lstio_session_new_args *args)
{
        char      *name;
        int        rc;

        if (args->lstio_ses_idp   == NULL || /* address for output sid */
            args->lstio_ses_key   == 0 || /* no key is specified */
            args->lstio_ses_namep == NULL || /* session name */
            args->lstio_ses_nmlen <= 0 ||
            args->lstio_ses_nmlen > LST_NAME_SIZE)
                return -EINVAL;

        LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1);
        if (name == NULL)
                return -ENOMEM;

	if (copy_from_user(name, args->lstio_ses_namep,
			   args->lstio_ses_nmlen)) {
                LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
                return -EFAULT;
        }

        name[args->lstio_ses_nmlen] = 0;

	rc = lstcon_session_new(name,
				args->lstio_ses_key,
				args->lstio_ses_feats,
				args->lstio_ses_force,
				args->lstio_ses_timeout,
				args->lstio_ses_idp);

	LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
	return rc;
}
Esempio n. 8
0
/* Handle incoming ZC request from sender.
 * NB: it's called only from read_handler, so we're sure that
 * the conn cannot become zombie in the middle of processing */
int
usocklnd_handle_zc_req(usock_peer_t *peer, __u64 cookie)
{
        usock_conn_t   *conn;
        usock_zc_ack_t *zc_ack;
        int             type;
        int             rc;
        int             dummy;

        LIBCFS_ALLOC (zc_ack, sizeof(*zc_ack));
        if (zc_ack == NULL)
                return -ENOMEM;
        zc_ack->zc_cookie = cookie;

        /* Let's assume that CONTROL is the best type for zcack,
         * but userspace clients don't use typed connections */
        if (the_lnet.ln_pid & LNET_PID_USERFLAG)
                type = SOCKLND_CONN_ANY;
        else
                type = SOCKLND_CONN_CONTROL;

        rc = usocklnd_find_or_create_conn(peer, type, &conn, NULL, zc_ack,
                                          &dummy);
        if (rc != 0) {
                LIBCFS_FREE (zc_ack, sizeof(*zc_ack));
                return rc;
        }
        usocklnd_conn_decref(conn);

        return 0;
}
Esempio n. 9
0
static int
lst_group_del_ioctl(lstio_group_del_args_t *args)
{
	int rc;
	char *name;

	if (args->lstio_grp_key != console_session.ses_key)
		return -EACCES;

	if (!args->lstio_grp_namep ||
	    args->lstio_grp_nmlen <= 0 ||
	    args->lstio_grp_nmlen > LST_NAME_SIZE)
		return -EINVAL;

	LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
	if (!name)
		return -ENOMEM;

	if (copy_from_user(name, args->lstio_grp_namep,
			   args->lstio_grp_nmlen)) {
		LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
		return -EFAULT;
	}

	name[args->lstio_grp_nmlen] = 0;

	rc = lstcon_group_del(name);

	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);

	return rc;
}
Esempio n. 10
0
int
cfs_wi_startup (void)
{
        int i;
        int n;
        int rc;

        cfs_wi_data.wi_nthreads = 0;
        cfs_wi_data.wi_nsched   = CFS_WI_NSCHED;
        LIBCFS_ALLOC(cfs_wi_data.wi_scheds,
                     cfs_wi_data.wi_nsched * sizeof(cfs_wi_sched_t));
        if (cfs_wi_data.wi_scheds == NULL)
                return -ENOMEM;

        cfs_spin_lock_init(&cfs_wi_data.wi_glock);
        for (i = 0; i < cfs_wi_data.wi_nsched; i++)
                cfs_wi_sched_init(&cfs_wi_data.wi_scheds[i]);

#ifdef __KERNEL__
        n = cfs_num_online_cpus();
        for (i = 0; i <= n; i++) {
                rc = cfs_wi_start_thread(cfs_wi_scheduler,
                                         (void *)(long_ptr_t)(i == n ? -1 : i));
                if (rc != 0) {
                        CERROR ("Can't spawn workitem scheduler: %d\n", rc);
                        cfs_wi_shutdown();
                        return rc;
                }
        }
#else
        n = rc = 0;
#endif

        return 0;
}
Esempio n. 11
0
static int
lst_group_update_ioctl(lstio_group_update_args_t *args)
{
	int     rc;
	char   *name;

	if (args->lstio_grp_key != console_session.ses_key)
		return -EACCES;

	if (args->lstio_grp_resultp == NULL ||
	    args->lstio_grp_namep == NULL ||
	    args->lstio_grp_nmlen <= 0 ||
	    args->lstio_grp_nmlen > LST_NAME_SIZE)
		return -EINVAL;

	LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
	if (name == NULL)
		return -ENOMEM;

	if (copy_from_user(name,
			   args->lstio_grp_namep,
			   args->lstio_grp_nmlen)) {
		LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
		return -EFAULT;
	}

	name[args->lstio_grp_nmlen] = 0;

	switch (args->lstio_grp_opc) {
	case LST_GROUP_CLEAN:
		rc = lstcon_group_clean(name, args->lstio_grp_args);
		break;

	case LST_GROUP_REFRESH:
		rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
		break;

	case LST_GROUP_RMND:
		if (args->lstio_grp_count  <= 0 ||
		    args->lstio_grp_idsp == NULL) {
			rc = -EINVAL;
			break;
		}
		rc = lstcon_nodes_remove(name, args->lstio_grp_count,
					 args->lstio_grp_idsp,
					 args->lstio_grp_resultp);
		break;

	default:
		rc = -EINVAL;
		break;
	}

	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);

	return rc;
}
Esempio n. 12
0
int
LNetEQAlloc(unsigned int count, lnet_eq_handler_t callback,
            lnet_handle_eq_t *handle)
{
        lnet_eq_t     *eq;

        LASSERT (the_lnet.ln_init);
        LASSERT (the_lnet.ln_refcount > 0);

        /* We need count to be a power of 2 so that when eq_{enq,deq}_seq
         * overflow, they don't skip entries, so the queue has the same
         * apparant capacity at all times */

        if (count != LOWEST_BIT_SET(count)) {   /* not a power of 2 already */
                do {                    /* knock off all but the top bit... */
                        count &= ~LOWEST_BIT_SET (count);
                } while (count != LOWEST_BIT_SET(count));

                count <<= 1;                             /* ...and round up */
        }

        if (count == 0)        /* catch bad parameter / overflow on roundup */
                return (-EINVAL);

        eq = lnet_eq_alloc();
        if (eq == NULL)
                return (-ENOMEM);

        LIBCFS_ALLOC(eq->eq_events, count * sizeof(lnet_event_t));
        if (eq->eq_events == NULL) {
                LNET_LOCK();
                lnet_eq_free (eq);
                LNET_UNLOCK();

                return -ENOMEM;
        }

        /* NB this resets all event sequence numbers to 0, to be earlier
         * than eq_deq_seq */
        memset(eq->eq_events, 0, count * sizeof(lnet_event_t));

        eq->eq_deq_seq = 1;
        eq->eq_enq_seq = 1;
        eq->eq_size = count;
        eq->eq_refcount = 0;
        eq->eq_callback = callback;

        LNET_LOCK();

        lnet_initialise_handle (&eq->eq_lh, LNET_COOKIE_TYPE_EQ);
        list_add (&eq->eq_list, &the_lnet.ln_active_eqs);

        LNET_UNLOCK();

        lnet_eq2handle(handle, eq);
        return (0);
}
Esempio n. 13
0
int
lwt_init ()
{
	int     i;
        int     j;

        for (i = 0; i < cfs_num_online_cpus(); i++)
                if (lwt_cpus[i].lwtc_current_page != NULL)
                        return (-EALREADY);

        LASSERT (!lwt_enabled);

	/* NULL pointers, zero scalars */
	memset (lwt_cpus, 0, sizeof (lwt_cpus));
	lwt_pages_per_cpu =
		LWT_MEMORY / (cfs_num_online_cpus() * PAGE_CACHE_SIZE);

	for (i = 0; i < cfs_num_online_cpus(); i++)
		for (j = 0; j < lwt_pages_per_cpu; j++) {
			struct page *page = alloc_page(GFP_KERNEL);
			lwt_page_t  *lwtp;

			if (page == NULL) {
				CERROR ("Can't allocate page\n");
                                lwt_fini ();
				return (-ENOMEM);
			}

                        LIBCFS_ALLOC(lwtp, sizeof (*lwtp));
			if (lwtp == NULL) {
				CERROR ("Can't allocate lwtp\n");
                                __free_page(page);
				lwt_fini ();
				return (-ENOMEM);
			}

                        lwtp->lwtp_page = page;
                        lwtp->lwtp_events = page_address(page);
			memset(lwtp->lwtp_events, 0, PAGE_CACHE_SIZE);

			if (j == 0) {
				CFS_INIT_LIST_HEAD (&lwtp->lwtp_list);
				lwt_cpus[i].lwtc_current_page = lwtp;
			} else {
				cfs_list_add (&lwtp->lwtp_list,
				    &lwt_cpus[i].lwtc_current_page->lwtp_list);
			}
                }

        lwt_enabled = 1;
        cfs_mb();

        LWT_EVENT(0,0,0,0);

        return (0);
}
Esempio n. 14
0
struct lnet_xport *
lx_new(struct lnet_xport_int *lxi)
{
	struct lnet_xport *lx;

	LIBCFS_ALLOC(lx, sizeof(*lx));
	if (lx)
		lx->lx_tab = lxi;
	return (lx);
}
Esempio n. 15
0
int
libcfs_socketpair(cfs_socket_t **sockp)
{
        int rc, i, fdp[2];

        LIBCFS_ALLOC(sockp[0], sizeof(cfs_socket_t));
        if (sockp[0] == NULL) {
                CERROR ("Can't alloc memory for cfs_socket_t (1)\n");
                return -ENOMEM;
        }

        LIBCFS_ALLOC(sockp[1], sizeof(cfs_socket_t));
        if (sockp[1] == NULL) {
                CERROR ("Can't alloc memory for cfs_socket_t (2)\n");
                LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
                return -ENOMEM;
        }

        rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fdp);
        if (rc != 0) {
                rc = -errno;
                CERROR ("Cannot create socket pair\n");
                LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
                LIBCFS_FREE(sockp[1], sizeof(cfs_socket_t));
                return rc;
        }

        sockp[0]->s_fd = fdp[0];
        sockp[1]->s_fd = fdp[1];

        for (i = 0; i < 2; i++) {
                rc = libcfs_fcntl_nonblock(sockp[i]);
                if (rc) {
                        libcfs_sock_release(sockp[0]);
                        libcfs_sock_release(sockp[1]);
                        return rc;
                }
        }

        return 0;
}
Esempio n. 16
0
/**
 * Finds or creates struct nidrange.
 *
 * Checks if \a src is a valid network name, looks for corresponding
 * nidrange on the ist of nidranges (\a nidlist), creates new struct
 * nidrange if it is not found.
 *
 * \retval pointer to struct nidrange matching network specified via \a src
 * \retval NULL if \a src does not match any network
 */
static struct nidrange *
add_nidrange(const struct lstr *src,
             cfs_list_t *nidlist)
{
    struct netstrfns *nf;
    struct nidrange *nr;
    int endlen;
    unsigned netnum;

    if (src->ls_len >= LNET_NIDSTR_SIZE)
        return NULL;

    nf = libcfs_namenum2netstrfns(src->ls_str);
    if (nf == NULL)
        return NULL;
    endlen = src->ls_len - strlen(nf->nf_name);
    if (endlen == 0)
        /* network name only, e.g. "elan" or "tcp" */
        netnum = 0;
    else {
        /* e.g. "elan25" or "tcp23", refuse to parse if
         * network name is not appended with decimal or
         * hexadecimal number */
        if (!libcfs_str2num_check(src->ls_str + strlen(nf->nf_name),
                                  endlen, &netnum,
                                  0, MAX_NUMERIC_VALUE))
            return NULL;
    }

    cfs_list_for_each_entry(nr, nidlist, nr_link) {
        if (nr->nr_netstrfns != nf)
            continue;
        if (nr->nr_netnum != netnum)
            continue;
        return nr;
    }

    LIBCFS_ALLOC(nr, sizeof(struct nidrange));
    if (nr == NULL)
        return NULL;
    cfs_list_add_tail(&nr->nr_link, nidlist);
    CFS_INIT_LIST_HEAD(&nr->nr_addrranges);
    nr->nr_netstrfns = nf;
    nr->nr_all = 0;
    nr->nr_netnum = netnum;

    return nr;
}
Esempio n. 17
0
/* called when opening /dev/device */
static int libcfs_psdev_open(unsigned long flags, void *args)
{
	struct libcfs_device_userstate *ldu;
	ENTRY;

	try_module_get(THIS_MODULE);

	LIBCFS_ALLOC(ldu, sizeof(*ldu));
	if (ldu != NULL) {
		ldu->ldu_memhog_pages = 0;
		ldu->ldu_memhog_root_page = NULL;
	}
	*(struct libcfs_device_userstate **)args = ldu;

	RETURN(0);
}
Esempio n. 18
0
/**
 * Parses \<range_expr\> token of the syntax.
 *
 * \retval pointer to allocated range_expr and initialized
 * range_expr::re_lo, range_expr::re_hi and range_expr:re_stride if \a
 `* src parses to
 * \<number\> |
 * \<number\> '-' \<number\> |
 * \<number\> '-' \<number\> '/' \<number\>
 * \retval NULL othersize
 */
static struct range_expr *
parse_range_expr(struct lstr *src, unsigned min, unsigned max)
{
    struct lstr tok;
    struct range_expr *expr;

    LIBCFS_ALLOC(expr, sizeof(struct range_expr));
    if (expr == NULL)
        return NULL;

    if (libcfs_str2num_check(src->ls_str, src->ls_len, &expr->re_lo,
                             min, max)) {
        /* <number> is parsed */
        expr->re_hi = expr->re_lo;
        expr->re_stride = 1;
        return expr;
    }

    if (!gettok(src, '-', &tok))
        goto failed;
    if (!libcfs_str2num_check(tok.ls_str, tok.ls_len, &expr->re_lo,
                              min, max))
        goto failed;
    /* <number> - */
    if (libcfs_str2num_check(src->ls_str, src->ls_len, &expr->re_hi,
                             min, max)) {
        /* <number> - <number> is parsed */
        expr->re_stride = 1;
        return expr;
    }

    /* go to check <number> '-' <number> '/' <number> */
    if (gettok(src, '/', &tok)) {
        if (!libcfs_str2num_check(tok.ls_str, tok.ls_len,
                                  &expr->re_hi, min, max))
            goto failed;
        /* <number> - <number> / ... */
        if (libcfs_str2num_check(src->ls_str, src->ls_len,
                                 &expr->re_stride, min, max))
            /* <number> - <number> / <number> is parsed */
            return expr;
    }

failed:
    LIBCFS_FREE(expr, sizeof(struct range_expr));
    return NULL;
}
Esempio n. 19
0
static int
lst_stat_query_ioctl(struct lstio_stat_args *args)
{
        int             rc;
	char           *name = NULL;

        /* TODO: not finished */
        if (args->lstio_sta_key != console_session.ses_key)
                return -EACCES;

	if (args->lstio_sta_resultp == NULL)
		return -EINVAL;

	if (args->lstio_sta_idsp != NULL) {
		if (args->lstio_sta_count <= 0)
			return -EINVAL;

		rc = lstcon_nodes_stat(args->lstio_sta_count,
                                       args->lstio_sta_idsp,
                                       args->lstio_sta_timeout,
                                       args->lstio_sta_resultp);
	} else if (args->lstio_sta_namep != NULL) {
		if (args->lstio_sta_nmlen <= 0 ||
		    args->lstio_sta_nmlen > LST_NAME_SIZE)
			return -EINVAL;

		LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
		if (name == NULL)
			return -ENOMEM;

		rc = copy_from_user(name, args->lstio_sta_namep,
				    args->lstio_sta_nmlen);
		if (rc == 0)
			rc = lstcon_group_stat(name, args->lstio_sta_timeout,
					       args->lstio_sta_resultp);
		else
			rc = -EFAULT;

	} else {
		rc = -EINVAL;
	}

	if (name != NULL)
		LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
	return rc;
}
Esempio n. 20
0
int
libcfs_ip_str2addr(const char *str, int nob, __u32 *addr)
{
        int   a;
        int   b;
        int   c;
        int   d;
        int   n = nob;                          /* XscanfX */

        /* numeric IP? */
        if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 &&
            n == nob &&
            (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
            (c & ~0xff) == 0 && (d & ~0xff) == 0) {
                *addr = ((a<<24)|(b<<16)|(c<<8)|d);
                return 1;
        }

#if !defined(__KERNEL__) && defined HAVE_GETHOSTBYNAME
        /* known hostname? */
        if (('a' <= str[0] && str[0] <= 'z') ||
            ('A' <= str[0] && str[0] <= 'Z')) {
                char *tmp;

                LIBCFS_ALLOC(tmp, nob + 1);
                if (tmp != NULL) {
                        struct hostent *he;

                        memcpy(tmp, str, nob);
                        tmp[nob] = 0;

                        he = gethostbyname(tmp);

                        LIBCFS_FREE(tmp, nob);

                        if (he != NULL) {
                                __u32 ip = *(__u32 *)he->h_addr;

                                *addr = ntohl(ip);
                                return 1;
                        }
                }
        }
#endif
        return 0;
}
Esempio n. 21
0
struct cfs_cpt_table *
cfs_cpt_table_alloc(unsigned int ncpt)
{
	struct cfs_cpt_table *cptab;

	if (ncpt != 1) {
		CERROR("Can't support cpu partition number %d\n", ncpt);
		return NULL;
	}

	LIBCFS_ALLOC(cptab, sizeof(*cptab));
	if (cptab != NULL) {
		cptab->ctb_version = CFS_CPU_VERSION_MAGIC;
		cptab->ctb_nparts  = ncpt;
	}

	return cptab;
}
Esempio n. 22
0
static int
lst_nodes_add_ioctl(struct lstio_group_nodes_args *args)
{
	unsigned feats;
        int     rc;
        char   *name;

        if (args->lstio_grp_key != console_session.ses_key)
                return -EACCES;

        if (args->lstio_grp_idsp == NULL || /* array of ids */
            args->lstio_grp_count <= 0 ||
            args->lstio_grp_resultp == NULL ||
	    args->lstio_grp_featp == NULL ||
	    args->lstio_grp_namep == NULL ||
	    args->lstio_grp_nmlen <= 0 ||
            args->lstio_grp_nmlen > LST_NAME_SIZE)
                return -EINVAL;

        LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
        if (name == NULL)
                return -ENOMEM;

	if (copy_from_user(name, args->lstio_grp_namep,
                               args->lstio_grp_nmlen)) {
                LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);

                return -EFAULT;
        }

        name[args->lstio_grp_nmlen] = 0;

        rc = lstcon_nodes_add(name, args->lstio_grp_count,
			      args->lstio_grp_idsp, &feats,
			      args->lstio_grp_resultp);

	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
	if (rc == 0 &&
	    copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
		return -EINVAL;
	}

        return rc;
}
Esempio n. 23
0
int
libcfs_sock_create(cfs_socket_t **sockp, int *fatal,
                   __u32 local_ip, int local_port)
{
        int rc, fd, option;

        *fatal = 1;

        LIBCFS_ALLOC(*sockp, sizeof(cfs_socket_t));
        if (*sockp == NULL) {
                CERROR("Can't alloc memory for cfs_socket_t\n");
                return -ENOMEM;
        }

        fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd < 0) {
                rc = -errno;
                CERROR("Cannot create socket: %d\n", rc);
                LIBCFS_FREE(*sockp, sizeof(cfs_socket_t));
                return rc;
        }

        (*sockp)->s_fd = fd;

        option = 1;
        rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
                        &option, sizeof(option));
        if (rc != 0) {
                rc = -errno;
                CERROR("Cannot set SO_REUSEADDR for socket: %d\n", rc);
                libcfs_sock_release(*sockp);
                return rc;
        }

        rc = libcfs_sock_bind(*sockp, local_ip, local_port);
        if (rc != 0) {
                *fatal = 0;
                libcfs_sock_release(*sockp);
        }

        return rc;
}
Esempio n. 24
0
/**
 * Parses \<addrrange\> token on the syntax.
 *
 * Allocates struct addrrange and links to \a nidrange via
 * (nidrange::nr_addrranges)
 *
 * \retval 0 if \a src parses to '*' | \<ipaddr_range\> | \<cfs_expr_list\>
 * \retval -errno otherwise
 */
static int
parse_addrange(const struct cfs_lstr *src, struct nidrange *nidrange)
{
	struct addrrange *addrrange;

	if (src->ls_len == 1 && src->ls_str[0] == '*') {
		nidrange->nr_all = 1;
		return 0;
	}

	LIBCFS_ALLOC(addrrange, sizeof(struct addrrange));
	if (addrrange == NULL)
		return -ENOMEM;
	list_add_tail(&addrrange->ar_link, &nidrange->nr_addrranges);
	INIT_LIST_HEAD(&addrrange->ar_numaddr_ranges);

	return nidrange->nr_netstrfns->nf_parse_addrlist(src->ls_str,
						src->ls_len,
						&addrrange->ar_numaddr_ranges);
}
Esempio n. 25
0
static int
lst_batch_query_ioctl(lstio_batch_query_args_t *args)
{
	char   *name;
	int     rc;

	if (args->lstio_bat_key != console_session.ses_key)
		return -EACCES;

	if (args->lstio_bat_resultp == NULL ||
	    args->lstio_bat_namep == NULL ||
	    args->lstio_bat_nmlen <= 0 ||
	    args->lstio_bat_nmlen > LST_NAME_SIZE)
		return -EINVAL;

	if (args->lstio_bat_testidx < 0)
		return -EINVAL;

	LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
	if (name == NULL)
		return -ENOMEM;

	if (copy_from_user(name,
			       args->lstio_bat_namep,
			       args->lstio_bat_nmlen)) {
		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
		return -EFAULT;
	}

	name[args->lstio_bat_nmlen] = 0;

	rc = lstcon_test_batch_query(name,
				     args->lstio_bat_testidx,
				     args->lstio_bat_client,
				     args->lstio_bat_timeout,
				     args->lstio_bat_resultp);

	LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);

	return rc;
}
Esempio n. 26
0
int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
			 struct libcfs_ioctl_hdr __user *uhdr)
{
	struct libcfs_ioctl_hdr   hdr;
	int err = 0;
	ENTRY;

	if (copy_from_user(&hdr, uhdr, sizeof(hdr)))
		RETURN(-EFAULT);

	if (hdr.ioc_version != LIBCFS_IOCTL_VERSION &&
	    hdr.ioc_version != LIBCFS_IOCTL_VERSION2) {
		CERROR("libcfs ioctl: version mismatch expected %#x, got %#x\n",
		       LIBCFS_IOCTL_VERSION, hdr.ioc_version);
		RETURN(-EINVAL);
	}

	if (hdr.ioc_len < sizeof(struct libcfs_ioctl_hdr)) {
		CERROR("libcfs ioctl: user buffer too small for ioctl\n");
		RETURN(-EINVAL);
	}

	if (hdr.ioc_len > LIBCFS_IOC_DATA_MAX) {
		CERROR("libcfs ioctl: user buffer is too large %d/%d\n",
		       hdr.ioc_len, LIBCFS_IOC_DATA_MAX);
		RETURN(-EINVAL);
	}

	LIBCFS_ALLOC(*hdr_pp, hdr.ioc_len);
	if (*hdr_pp == NULL)
		RETURN(-ENOMEM);

	if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len))
		GOTO(failed, err = -EFAULT);

	RETURN(0);
failed:
	LIBCFS_FREE(*hdr_pp, hdr.ioc_len);
	RETURN(err);
}
Esempio n. 27
0
static int __proc_cpt_table(void *data, int write,
			    loff_t pos, void __user *buffer, int nob)
{
	char *buf = NULL;
	int   len = 4096;
	int   rc  = 0;

	if (write)
		return -EPERM;

	LASSERT(cfs_cpt_table != NULL);

	while (1) {
		LIBCFS_ALLOC(buf, len);
		if (buf == NULL)
			return -ENOMEM;

		rc = cfs_cpt_table_print(cfs_cpt_table, buf, len);
		if (rc >= 0)
			break;

		if (rc == -EFBIG) {
			LIBCFS_FREE(buf, len);
			len <<= 1;
			continue;
		}
		goto out;
	}

	if (pos >= rc) {
		rc = 0;
		goto out;
	}

	rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
 out:
	if (buf != NULL)
		LIBCFS_FREE(buf, len);
	return rc;
}
Esempio n. 28
0
int
lst_nodes_add_ioctl(lstio_group_nodes_args_t *args)
{
        int     rc;
        char   *name;

        if (args->lstio_grp_key != console_session.ses_key)
                return -EACCES;

        if (args->lstio_grp_idsp == NULL || /* array of ids */
            args->lstio_grp_count <= 0 ||
            args->lstio_grp_resultp == NULL ||
            args->lstio_grp_namep == NULL ||
            args->lstio_grp_nmlen <= 0 || 
            args->lstio_grp_nmlen > LST_NAME_SIZE)
                return -EINVAL;

        LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
        if (name == NULL)
                return -ENOMEM;

        if (cfs_copy_from_user(name, args->lstio_grp_namep,
                               args->lstio_grp_nmlen)) {
                LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);

                return -EFAULT;
        }

        name[args->lstio_grp_nmlen] = 0;

        rc = lstcon_nodes_add(name, args->lstio_grp_count,
                              args->lstio_grp_idsp,
                              args->lstio_grp_resultp);

        LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);

        return rc;
}
Esempio n. 29
0
struct lc_watchdog *lc_watchdog_add(int timeout,
                                    void (*callback)(pid_t, void *),
                                    void *data)
{
        struct lc_watchdog *lcw = NULL;
        ENTRY;

        LIBCFS_ALLOC(lcw, sizeof(*lcw));
        if (lcw == NULL) {
                CDEBUG(D_INFO, "Could not allocate new lc_watchdog\n");
                RETURN(ERR_PTR(-ENOMEM));
        }

        cfs_spin_lock_init(&lcw->lcw_lock);
        lcw->lcw_refcount = 1; /* refcount for owner */
        lcw->lcw_task     = cfs_current();
        lcw->lcw_pid      = cfs_curproc_pid();
        lcw->lcw_callback = (callback != NULL) ? callback : lc_watchdog_dumplog;
        lcw->lcw_data     = data;
        lcw->lcw_state    = LC_WATCHDOG_DISABLED;

        CFS_INIT_LIST_HEAD(&lcw->lcw_list);
        cfs_timer_init(&lcw->lcw_timer, lcw_cb, lcw);

        cfs_down(&lcw_refcount_sem);
        if (++lcw_refcount == 1)
                lcw_dispatch_start();
        cfs_up(&lcw_refcount_sem);

        /* Keep this working in case we enable them by default */
        if (lcw->lcw_state == LC_WATCHDOG_ENABLED) {
                lcw->lcw_last_touched = cfs_time_current();
                cfs_timer_arm(&lcw->lcw_timer, cfs_time_seconds(timeout) +
                              cfs_time_current());
        }

        RETURN(lcw);
}
Esempio n. 30
0
int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
			 const struct libcfs_ioctl_hdr __user *uhdr)
{
	struct libcfs_ioctl_hdr hdr;
	int err = 0;

	if (copy_from_user(&hdr, uhdr, sizeof(hdr)))
		return -EFAULT;

	if (hdr.ioc_version != LIBCFS_IOCTL_VERSION &&
	    hdr.ioc_version != LIBCFS_IOCTL_VERSION2) {
		CERROR("libcfs ioctl: version mismatch expected %#x, got %#x\n",
		       LIBCFS_IOCTL_VERSION, hdr.ioc_version);
		return -EINVAL;
	}

	if (hdr.ioc_len < sizeof(struct libcfs_ioctl_data)) {
		CERROR("libcfs ioctl: user buffer too small for ioctl\n");
		return -EINVAL;
	}

	if (hdr.ioc_len > LIBCFS_IOC_DATA_MAX) {
		CERROR("libcfs ioctl: user buffer is too large %d/%d\n",
		       hdr.ioc_len, LIBCFS_IOC_DATA_MAX);
		return -EINVAL;
	}

	LIBCFS_ALLOC(*hdr_pp, hdr.ioc_len);
	if (!*hdr_pp)
		return -ENOMEM;

	if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) {
		LIBCFS_FREE(*hdr_pp, hdr.ioc_len);
		err = -EFAULT;
	}
	return err;
}