Ejemplo n.º 1
0
int cfs_daemonize_ctxt(char *str) {

        cfs_daemonize(str);
#ifndef HAVE_UNSHARE_FS_STRUCT
        {
        struct task_struct *tsk = current;
        struct fs_struct *fs = NULL;
        fs = copy_fs_struct(tsk->fs);
        if (fs == NULL)
                return -ENOMEM;
        exit_fs(tsk);
        tsk->fs = fs;
        }
#else
        unshare_fs_struct();
#endif
        return 0;
}
Ejemplo n.º 2
0
int
lnet_acceptor(void *arg)
{
        char           name[16];
        cfs_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);

        snprintf(name, sizeof(name), "acceptor_%03d", accept_port);
        cfs_daemonize(name);
        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;
        cfs_mt_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 %u.%u.%u.%u: "
                               "insecure port %d\n",
                               HIPQUAD(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 "
                               "%u.%u.%u.%u\n", rc, HIPQUAD(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;

        LCONSOLE(0, "Acceptor stopping\n");

        /* unblock lnet_acceptor_stop() */
        cfs_mt_complete(&lnet_acceptor_state.pta_signal);
        return 0;
}
Ejemplo n.º 3
0
static int lcw_dispatch_main(void *data)
{
        int                 rc = 0;
        unsigned long       flags;
        struct lc_watchdog *lcw;
        CFS_LIST_HEAD      (zombies);

        ENTRY;

        cfs_daemonize("lc_watchdogd");

        SIGNAL_MASK_LOCK(current, flags);
        sigfillset(&current->blocked);
        RECALC_SIGPENDING;
        SIGNAL_MASK_UNLOCK(current, flags);

        cfs_complete(&lcw_start_completion);

        while (1) {
                int dumplog = 1;

                cfs_wait_event_interruptible(lcw_event_waitq,
                                             is_watchdog_fired(), rc);
                CDEBUG(D_INFO, "Watchdog got woken up...\n");
                if (cfs_test_bit(LCW_FLAG_STOP, &lcw_flags)) {
                        CDEBUG(D_INFO, "LCW_FLAG_STOP was set, shutting down...\n");

                        cfs_spin_lock_bh(&lcw_pending_timers_lock);
                        rc = !cfs_list_empty(&lcw_pending_timers);
                        cfs_spin_unlock_bh(&lcw_pending_timers_lock);
                        if (rc) {
                                CERROR("pending timers list was not empty at "
                                       "time of watchdog dispatch shutdown\n");
                        }
                        break;
                }

                cfs_spin_lock_bh(&lcw_pending_timers_lock);
                while (!cfs_list_empty(&lcw_pending_timers)) {
                        int is_dumplog;

                        lcw = cfs_list_entry(lcw_pending_timers.next,
                                             struct lc_watchdog, lcw_list);
                        /* +1 ref for callback to make sure lwc wouldn't be
                         * deleted after releasing lcw_pending_timers_lock */
                        lcw->lcw_refcount++;
                        cfs_spin_unlock_bh(&lcw_pending_timers_lock);

                        /* lock ordering */
                        cfs_spin_lock_bh(&lcw->lcw_lock);
                        cfs_spin_lock_bh(&lcw_pending_timers_lock);

                        if (cfs_list_empty(&lcw->lcw_list)) {
                                /* already removed from pending list */
                                lcw->lcw_refcount--; /* -1 ref for callback */
                                if (lcw->lcw_refcount == 0)
                                        cfs_list_add(&lcw->lcw_list, &zombies);
                                cfs_spin_unlock_bh(&lcw->lcw_lock);
                                /* still hold lcw_pending_timers_lock */
                                continue;
                        }

                        cfs_list_del_init(&lcw->lcw_list);
                        lcw->lcw_refcount--; /* -1 ref for pending list */

                        cfs_spin_unlock_bh(&lcw_pending_timers_lock);
                        cfs_spin_unlock_bh(&lcw->lcw_lock);

                        CDEBUG(D_INFO, "found lcw for pid " LPPID "\n",
                               lcw->lcw_pid);
                        lcw_dump_stack(lcw);

                        is_dumplog = lcw->lcw_callback == lc_watchdog_dumplog;
                        if (lcw->lcw_state != LC_WATCHDOG_DISABLED &&
                            (dumplog || !is_dumplog)) {
                                lcw->lcw_callback(lcw->lcw_pid, lcw->lcw_data);
                                if (dumplog && is_dumplog)
                                        dumplog = 0;
                        }

                        cfs_spin_lock_bh(&lcw_pending_timers_lock);
                        lcw->lcw_refcount--; /* -1 ref for callback */
                        if (lcw->lcw_refcount == 0)
                                cfs_list_add(&lcw->lcw_list, &zombies);
                }
                cfs_spin_unlock_bh(&lcw_pending_timers_lock);

                while (!cfs_list_empty(&zombies)) {
                        lcw = cfs_list_entry(lcw_pending_timers.next,
                                         struct lc_watchdog, lcw_list);
                        cfs_list_del(&lcw->lcw_list);
                        LIBCFS_FREE(lcw, sizeof(*lcw));
                }
        }

        cfs_complete(&lcw_stop_completion);

        RETURN(rc);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
static int osp_precreate_thread(void *_arg)
{
	struct osp_device	*d = _arg;
	struct ptlrpc_thread	*thread = &d->opd_pre_thread;
	struct l_wait_info	 lwi = { 0 };
	char			 pname[16];
	struct lu_env		 env;
	int			 rc;

	ENTRY;

	sprintf(pname, "osp-pre-%u", d->opd_index);
	cfs_daemonize(pname);

	rc = lu_env_init(&env, d->opd_dt_dev.dd_lu_dev.ld_type->ldt_ctx_tags);
	if (rc) {
		CERROR("%s: init env error: rc = %d\n", d->opd_obd->obd_name,
		       rc);
		RETURN(rc);
	}

	spin_lock(&d->opd_pre_lock);
	thread->t_flags = SVC_RUNNING;
	spin_unlock(&d->opd_pre_lock);
	cfs_waitq_signal(&thread->t_ctl_waitq);

	while (osp_precreate_running(d)) {
		/*
		 * need to be connected to OST
		 */
		while (osp_precreate_running(d)) {
			l_wait_event(d->opd_pre_waitq,
				     !osp_precreate_running(d) ||
				     d->opd_new_connection,
				     &lwi);

			if (!d->opd_new_connection)
				continue;

			d->opd_new_connection = 0;
			d->opd_got_disconnected = 0;
			break;
		}

		if (!osp_precreate_running(d))
			break;

		LASSERT(d->opd_obd->u.cli.cl_seq != NULL);
		if (d->opd_obd->u.cli.cl_seq->lcs_exp == NULL) {
			/* Get new sequence for client first */
			LASSERT(d->opd_exp != NULL);
			d->opd_obd->u.cli.cl_seq->lcs_exp =
			class_export_get(d->opd_exp);
			rc = osp_init_pre_fid(d);
			if (rc != 0) {
				class_export_put(d->opd_exp);
				d->opd_obd->u.cli.cl_seq->lcs_exp = NULL;
				CERROR("%s: init pre fid error: rc = %d\n",
				       d->opd_obd->obd_name, rc);
				continue;
			}
		}

		osp_statfs_update(d);

		/*
		 * Clean up orphans or recreate missing objects.
		 */
		rc = osp_precreate_cleanup_orphans(&env, d);
		if (rc != 0)
			continue;
		/*
		 * connected, can handle precreates now
		 */
		while (osp_precreate_running(d)) {
			l_wait_event(d->opd_pre_waitq,
				     !osp_precreate_running(d) ||
				     osp_precreate_near_empty(&env, d) ||
				     osp_statfs_need_update(d) ||
				     d->opd_got_disconnected, &lwi);

			if (!osp_precreate_running(d))
				break;

			/* something happened to the connection
			 * have to start from the beginning */
			if (d->opd_got_disconnected)
				break;

			if (osp_statfs_need_update(d))
				osp_statfs_update(d);

			/* To avoid handling different seq in precreate/orphan
			 * cleanup, it will hold precreate until current seq is
			 * used up. */
			if (unlikely(osp_precreate_end_seq(&env, d) &&
			    !osp_create_end_seq(&env, d)))
				continue;

			if (unlikely(osp_precreate_end_seq(&env, d) &&
				     osp_create_end_seq(&env, d))) {
				LCONSOLE_INFO("%s:"LPX64" is used up."
					      " Update to new seq\n",
					      d->opd_obd->obd_name,
					 fid_seq(&d->opd_pre_last_created_fid));
				rc = osp_precreate_rollover_new_seq(&env, d);
				if (rc)
					continue;
			}

			if (osp_precreate_near_empty(&env, d)) {
				rc = osp_precreate_send(&env, d);
				/* osp_precreate_send() sets opd_pre_status
				 * in case of error, that prevent the using of
				 * failed device. */
				if (rc < 0 && rc != -ENOSPC &&
				    rc != -ETIMEDOUT && rc != -ENOTCONN)
					CERROR("%s: cannot precreate objects:"
					       " rc = %d\n",
					       d->opd_obd->obd_name, rc);
			}
		}
	}

	thread->t_flags = SVC_STOPPED;
	lu_env_fini(&env);
	cfs_waitq_signal(&thread->t_ctl_waitq);

	RETURN(0);
}