Пример #1
0
static int
cfs_wi_scheduler (void *arg)
{
        int             id     = (int)(long_ptr_t) arg;
        int             serial = (id == -1);
        char            name[24];
        cfs_wi_sched_t *sched;

        if (serial) {
                sched = &cfs_wi_data.wi_scheds[cfs_wi_data.wi_nsched - 1];
                cfs_daemonize("wi_serial_sd");
        } else {
                /* will be sched = &cfs_wi_data.wi_scheds[id] in the future */
                sched = &cfs_wi_data.wi_scheds[0];
                snprintf(name, sizeof(name), "cfs_wi_sd%03d", id);
                cfs_daemonize(name);
        }

        cfs_block_allsigs();

        cfs_wi_sched_lock(sched);

        while (!sched->ws_shuttingdown) {
                int             nloops = 0;
                int             rc;
                cfs_workitem_t *wi;

                while (!cfs_list_empty(&sched->ws_runq) &&
                       nloops < CFS_WI_RESCHED) {
                        wi = cfs_list_entry(sched->ws_runq.next,
                                            cfs_workitem_t, wi_list);
                        LASSERT (wi->wi_scheduled && !wi->wi_running);

                        cfs_list_del_init(&wi->wi_list);

                        wi->wi_running   = 1;
                        wi->wi_scheduled = 0;
                        cfs_wi_sched_unlock(sched);
                        nloops++;

                        rc = (*wi->wi_action) (wi);

                        cfs_wi_sched_lock(sched);
                        if (rc != 0) /* WI should be dead, even be freed! */
                                continue;

                        wi->wi_running = 0;
                        if (cfs_list_empty(&wi->wi_list))
                                continue;

                        LASSERT (wi->wi_scheduled);
                        /* wi is rescheduled, should be on rerunq now, we
                         * move it to runq so it can run action now */
                        cfs_list_move_tail(&wi->wi_list, &sched->ws_runq);
                }

                if (!cfs_list_empty(&sched->ws_runq)) {
                        cfs_wi_sched_unlock(sched);
                        /* don't sleep because some workitems still
                         * expect me to come back soon */
                        cfs_cond_resched();
                        cfs_wi_sched_lock(sched);
                        continue;
                }

                cfs_wi_sched_unlock(sched);
                cfs_wait_event_interruptible_exclusive(sched->ws_waitq,
                                !cfs_wi_sched_cansleep(sched), rc);
                cfs_wi_sched_lock(sched);
        }

        cfs_wi_sched_unlock(sched);

        cfs_spin_lock(&cfs_wi_data.wi_glock);
        cfs_wi_data.wi_nthreads--;
        cfs_spin_unlock(&cfs_wi_data.wi_glock);
        return 0;
}
Пример #2
0
int
lnet_acceptor(void *arg)
{
	socket_t  *newsock;
	int	    rc;
	__u32	  magic;
	__u32	  peer_ip;
	int	    peer_port;
	int	    secure = (int)((long_ptr_t)arg);

	LASSERT(lnet_acceptor_state.pta_sock == NULL);

	cfs_block_allsigs();

	rc = libcfs_sock_listen(&lnet_acceptor_state.pta_sock,
				0, accept_port, accept_backlog);
	if (rc != 0) {
		if (rc == -EADDRINUSE)
			LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port %d: port already in use\n",
					   accept_port);
		else
			LCONSOLE_ERROR_MSG(0x123, "Can't start acceptor on port %d: unexpected error %d\n",
					   accept_port, rc);

		lnet_acceptor_state.pta_sock = NULL;
	} else {
		LCONSOLE(0, "Accept %s, port %d\n", accept_type, accept_port);
	}

	/* set init status and unblock parent */
	lnet_acceptor_state.pta_shutdown = rc;
	complete(&lnet_acceptor_state.pta_signal);

	if (rc != 0)
		return rc;

	while (!lnet_acceptor_state.pta_shutdown) {

		rc = libcfs_sock_accept(&newsock, lnet_acceptor_state.pta_sock);
		if (rc != 0) {
			if (rc != -EAGAIN) {
				CWARN("Accept error %d: pausing...\n", rc);
				cfs_pause(cfs_time_seconds(1));
			}
			continue;
		}

		/* maybe we're waken up with libcfs_sock_abort_accept() */
		if (lnet_acceptor_state.pta_shutdown) {
			libcfs_sock_release(newsock);
			break;
		}

		rc = libcfs_sock_getaddr(newsock, 1, &peer_ip, &peer_port);
		if (rc != 0) {
			CERROR("Can't determine new connection's address\n");
			goto failed;
		}

		if (secure && peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
			CERROR("Refusing connection from %pI4h: insecure port %d\n",
			       &peer_ip, peer_port);
			goto failed;
		}

		rc = libcfs_sock_read(newsock, &magic, sizeof(magic),
				      accept_timeout);
		if (rc != 0) {
			CERROR("Error %d reading connection request from %pI4h\n",
				rc, &peer_ip);
			goto failed;
		}

		rc = lnet_accept(newsock, magic);
		if (rc != 0)
			goto failed;

		continue;

failed:
		libcfs_sock_release(newsock);
	}

	libcfs_sock_release(lnet_acceptor_state.pta_sock);
	lnet_acceptor_state.pta_sock = NULL;

	CDEBUG(D_NET, "Acceptor stopping\n");

	/* unblock lnet_acceptor_stop() */
	complete(&lnet_acceptor_state.pta_signal);
	return 0;
}
Пример #3
0
static int mdt_ck_thread_main(void *args)
{
	struct mdt_device      *mdt = args;
	struct ptlrpc_thread   *thread = &mdt->mdt_ck_thread;
	struct lustre_capa_key *bkey = &mdt->mdt_capa_keys[0],
			       *rkey = &mdt->mdt_capa_keys[1];
	struct lustre_capa_key *tmp;
	struct lu_env           env;
	struct mdt_thread_info *info;
	struct md_device       *next;
	struct l_wait_info      lwi = { 0 };
	mdsno_t                 mdsnum;
	int                     rc;
	ENTRY;

	unshare_fs_struct();
	cfs_block_allsigs();

	thread_set_flags(thread, SVC_RUNNING);
	wake_up(&thread->t_ctl_waitq);

	rc = lu_env_init(&env, LCT_MD_THREAD|LCT_REMEMBER|LCT_NOREF);
	if (rc)
		RETURN(rc);

	thread->t_env = &env;
	env.le_ctx.lc_thread = thread;
	env.le_ctx.lc_cookie = 0x1;

	info = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
	LASSERT(info != NULL);

	tmp = &info->mti_capa_key;
	mdsnum = mdt_seq_site(mdt)->ss_node_id;
	while (1) {
		l_wait_event(thread->t_ctl_waitq,
			     thread_is_stopping(thread) ||
			     thread_is_event(thread),
			     &lwi);

		if (thread_is_stopping(thread))
			break;
		thread_clear_flags(thread, SVC_EVENT);

		if (cfs_time_before(cfs_time_current(), mdt->mdt_ck_expiry))
			break;

		*tmp = *rkey;
		make_capa_key(tmp, mdsnum, rkey->lk_keyid);

		next = mdt->mdt_child;
		rc = next->md_ops->mdo_update_capa_key(&env, next, tmp);
		if (!rc) {
			spin_lock(&capa_lock);
			*bkey = *rkey;
			*rkey = *tmp;
			spin_unlock(&capa_lock);

			rc = write_capa_keys(&env, mdt, mdt->mdt_capa_keys);
			if (rc) {
				spin_lock(&capa_lock);
				*rkey = *bkey;
				memset(bkey, 0, sizeof(*bkey));
				spin_unlock(&capa_lock);
			} else {
				set_capa_key_expiry(mdt);
				DEBUG_CAPA_KEY(D_SEC, rkey, "new");
			}
		}
		if (rc) {
			DEBUG_CAPA_KEY(D_ERROR, rkey, "update failed for");
			/* next retry is in 300 sec */
			mdt->mdt_ck_expiry = jiffies + 300 * HZ;
		}

		cfs_timer_arm(&mdt->mdt_ck_timer, mdt->mdt_ck_expiry);
		CDEBUG(D_SEC, "mdt_ck_timer %lu\n", mdt->mdt_ck_expiry);
	}
	lu_env_fini(&env);

	thread_set_flags(thread, SVC_STOPPED);
	wake_up(&thread->t_ctl_waitq);
	RETURN(0);
}