From a1e9641b7f90454608a9d465ec467a0f218afdc3 Mon Sep 17 00:00:00 2001 From: pschwan Date: Wed, 2 Apr 2003 03:56:24 +0000 Subject: [PATCH] b=957 - Infrastructure for the pinger thread; needs multi-rpc and some refinements - Add last_request_time to obd_export - Fixed export leak in lov_brw success case - test22 rears its head again: tar gets pissy if it can't access $PWD, which is common for homedirs at LLNL. cd to /tmp before running tar. Merged many of the changes from b_proto: - multi-rpc infrastructure, but not the key bits - removed some bitfield flags in favour of individual struct members - merged obd_brw_write and obd_brw_read into a single obd_brw_internal - move the Elan-related page wrangling from the IOD into the OSC --- lustre/ptlrpc/pinger.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 lustre/ptlrpc/pinger.c diff --git a/lustre/ptlrpc/pinger.c b/lustre/ptlrpc/pinger.c new file mode 100644 index 0000000..a657712 --- /dev/null +++ b/lustre/ptlrpc/pinger.c @@ -0,0 +1,178 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Portal-RPC reconnection and replay operations, for use in recovery. + * + * Copyright (c) 2003 Cluster File Systems, Inc. + * Author: Phil Schwan + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#define DEBUG_SUBSYSTEM S_RPC +#include +#include +#include "ptlrpc_internal.h" + +static struct ptlrpc_thread *pinger_thread = NULL; +static spinlock_t pinger_lock = SPIN_LOCK_UNLOCKED; +static struct list_head pinger_imports = LIST_HEAD_INIT(pinger_imports); + +int ptlrpc_pinger_add_import(struct obd_import *imp) +{ + ENTRY; + if (!list_empty(&imp->imp_pinger_chain)) + RETURN(-EALREADY); + + spin_lock(&pinger_lock); + list_add(&imp->imp_pinger_chain, &pinger_imports); + spin_unlock(&pinger_lock); + RETURN(0); +} + +int ptlrpc_pinger_del_import(struct obd_import *imp) +{ + ENTRY; + if (list_empty(&imp->imp_pinger_chain)) + RETURN(-EALREADY); + + spin_lock(&pinger_lock); + list_del_init(&imp->imp_pinger_chain); + spin_unlock(&pinger_lock); + RETURN(0); +} + +static void ptlrpc_pinger_do_stuff(void) +{ + + + +} + +static int ptlrpc_pinger_main(void *arg) +{ + struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg; + struct ptlrpc_thread *thread = data->thread; + unsigned long flags; + int rc = 0; + ENTRY; + + lock_kernel(); + ptlrpc_daemonize(); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + sigfillset(¤t->blocked); + recalc_sigpending(); +#else + spin_lock_irqsave(¤t->sigmask_lock, flags); + sigfillset(¤t->blocked); + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); +#endif + +#ifdef __arch_um__ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + sprintf(current->comm, "%s|%d", data->name, current->thread.extern_pid); +#endif +#else + strcpy(current->comm, data->name); +#endif + unlock_kernel(); + + /* Record that the thread is running */ + thread->t_flags = SVC_RUNNING; + wake_up(&thread->t_ctl_waitq); + + /* And now, loop forever on requests */ + while (1) { + struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ, NULL, NULL); + l_wait_event(thread->t_ctl_waitq, + thread->t_flags & SVC_STOPPING, &lwi); + + if (thread->t_flags & SVC_STOPPING) { + thread->t_flags &= ~SVC_STOPPING; + EXIT; + break; + } + ptlrpc_pinger_do_stuff(); + } + + thread->t_flags = SVC_STOPPED; + wake_up(&thread->t_ctl_waitq); + + CDEBUG(D_NET, "pinger thread exiting, process %d: rc = %d\n", + current->pid, rc); + return rc; +} + +int ptlrpc_pinger_start(void) +{ + struct l_wait_info lwi = { 0 }; + struct ptlrpc_svc_data d; + int rc; + ENTRY; + + spin_lock(&pinger_lock); + if (pinger_thread != NULL) + GOTO(out, rc = -EALREADY); + + OBD_ALLOC(pinger_thread, sizeof(*pinger_thread)); + if (pinger_thread == NULL) + GOTO(out, rc = -ENOMEM); + init_waitqueue_head(&pinger_thread->t_ctl_waitq); + + d.name = "Lustre pinger"; + d.thread = pinger_thread; + + /* CLONE_VM and CLONE_FILES just avoid a needless copy, because we + * just drop the VM and FILES in ptlrpc_daemonize() right away. */ + rc = kernel_thread(ptlrpc_pinger_main, &d, CLONE_VM | CLONE_FILES); + if (rc < 0) { + CERROR("cannot start thread: %d\n", rc); + OBD_FREE(pinger_thread, sizeof(*pinger_thread)); + GOTO(out, rc); + } + l_wait_event(pinger_thread->t_ctl_waitq, + pinger_thread->t_flags & SVC_RUNNING, &lwi); + + out: + spin_unlock(&pinger_lock); + RETURN(rc); +} + +int ptlrpc_stop_pinger(void) +{ + struct l_wait_info lwi = { 0 }; + int rc = 0; + ENTRY; + + spin_lock(&pinger_lock); + if (pinger_thread == NULL) + GOTO(out, rc = -EALREADY); + + pinger_thread->t_flags = SVC_STOPPING; + wake_up(&pinger_thread->t_ctl_waitq); + l_wait_event(pinger_thread->t_ctl_waitq, + (pinger_thread->t_flags & SVC_STOPPED), &lwi); + + OBD_FREE(pinger_thread, sizeof(*pinger_thread)); + + out: + spin_unlock(&pinger_lock); + RETURN(rc); +} -- 1.8.3.1