From patchwork Wed Oct 24 14:30:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 1638701 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 09294DF2AB for ; Wed, 24 Oct 2012 14:30:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934873Ab2JXOac (ORCPT ); Wed, 24 Oct 2012 10:30:32 -0400 Received: from mail-vc0-f174.google.com ([209.85.220.174]:40464 "EHLO mail-vc0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934933Ab2JXOab (ORCPT ); Wed, 24 Oct 2012 10:30:31 -0400 Received: by mail-vc0-f174.google.com with SMTP id fk26so598762vcb.19 for ; Wed, 24 Oct 2012 07:30:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=44QDmxSbJMRYZp7ZMMavzCzfAHrD9zjNR30U3W+vrX8=; b=DRkpo4B9wQ5yKNP20jXrsJuppmiYEumJkch3U8L7wKKTrFNWLfs9eNoDzxuluuhME2 aqs2QtyH1EowyvKNtaNCzKPsliHLCMvzfbIs7aKCsJoJqqYfQuvVH0bhiynMx5sKJkD3 nJMxlfH9bCmCCoP/ZjsDcHDLxizbHL0k5/SPjSx+CSr2fkvNxmTyFdn5CLNlqgWF8Rsl rbRA1itk8iafdXdT8yhRil9M5WoovxmntUVfXo88RmXTSpImHkk1r1XaWhY2p6FwZU9Q YqDRCoBqKiWz3bEJM0l71EBNyb45dTTPbdl1TdnRVbC4Aai0TXp5JuhsLO1aFXYrjFWl pwVA== Received: by 10.52.27.75 with SMTP id r11mr21779630vdg.94.1351089030738; Wed, 24 Oct 2012 07:30:30 -0700 (PDT) Received: from salusa.poochiereds.net (cpe-107-015-110-129.nc.res.rr.com. [107.15.110.129]) by mx.google.com with ESMTPS id dp6sm15387737vec.11.2012.10.24.07.30.29 (version=SSLv3 cipher=OTHER); Wed, 24 Oct 2012 07:30:29 -0700 (PDT) From: Jeff Layton To: bfields@fieldses.org Cc: linux-nfs@vger.kernel.org Subject: [PATCH v3 3/4] nfsd: pass info about the legacy recoverydir in environment variables Date: Wed, 24 Oct 2012 10:30:17 -0400 Message-Id: <1351089018-24551-4-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1351089018-24551-1-git-send-email-jlayton@redhat.com> References: <1351089018-24551-1-git-send-email-jlayton@redhat.com> X-Gm-Message-State: ALoCoQlTwsdN8iMjpQpYINiHoucDwCLbI3TLCuC742Tx6NrgTVkB4/DgifJ5sqbhI4lOUk/yIlJ+ Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org The usermodehelper upcall program can then decide to use this info as a (one-way) transition mechanism to the new scheme. When a "check" upcall occurs and the client doesn't exist in the database, we can look to see whether the directory exists. If it does, then we'd add the client to the database, remove the legacy recdir, and return success to the kernel to allow the recovery to proceed. For gracedone, we simply pass the v4recovery "topdir" so that the upcall can clean it out prior to returning to the kernel. A module parm is also added to disable the legacy conversion if the admin chooses. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4recover.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index aa165fd..782168d 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -932,10 +932,75 @@ module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog), S_IRUGO|S_IWUSR); MODULE_PARM_DESC(cltrack_prog, "Path to the nfsdcltrack upcall program"); +static bool cltrack_legacy_disable; +module_param(cltrack_legacy_disable, bool, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(cltrack_legacy_disable, + "Disable legacy recoverydir conversion. Default: false"); + +#define LEGACY_TOPDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_TOPDIR=" +#define LEGACY_RECDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_RECDIR=" + +static char * +nfsd4_cltrack_legacy_topdir(void) +{ + int copied; + size_t len; + char *result; + + if (cltrack_legacy_disable) + return NULL; + + len = strlen(LEGACY_TOPDIR_ENV_PREFIX) + + strlen(nfs4_recoverydir()) + 1; + + result = kmalloc(len, GFP_KERNEL); + if (!result) + return result; + + copied = snprintf(result, len, LEGACY_TOPDIR_ENV_PREFIX "%s", + nfs4_recoverydir()); + if (copied >= len) { + /* just return nothing if output was truncated */ + kfree(result); + return NULL; + } + + return result; +} + +static char * +nfsd4_cltrack_legacy_recdir(const char *recdir) +{ + int copied; + size_t len; + char *result; + + if (cltrack_legacy_disable) + return NULL; + + /* +1 is for '/' between "topdir" and "recdir" */ + len = strlen(LEGACY_RECDIR_ENV_PREFIX) + + strlen(nfs4_recoverydir()) + 1 + HEXDIR_LEN; + + result = kmalloc(len, GFP_KERNEL); + if (!result) + return result; + + copied = snprintf(result, len, LEGACY_RECDIR_ENV_PREFIX "%s/%s", + nfs4_recoverydir(), recdir); + if (copied >= len) { + /* just return nothing if output was truncated */ + kfree(result); + return NULL; + } + + return result; +} + static int -nfsd4_umh_cltrack_upcall(char *cmd, char *arg) +nfsd4_umh_cltrack_upcall(char *cmd, char *arg, char *legacy) { - char *envp[] = { NULL }; + char *envp[2]; char *argv[4]; int ret; @@ -946,6 +1011,10 @@ nfsd4_umh_cltrack_upcall(char *cmd, char *arg) dprintk("%s: cmd: %s\n", __func__, cmd); dprintk("%s: arg: %s\n", __func__, arg ? arg : "(null)"); + dprintk("%s: legacy: %s\n", __func__, legacy ? legacy : "(null)"); + + envp[0] = legacy; + envp[1] = NULL; argv[0] = (char *)cltrack_prog; argv[1] = cmd; @@ -991,7 +1060,7 @@ bin_to_hex_dup(const unsigned char *src, int srclen) static int nfsd4_umh_cltrack_init(struct net __attribute__((unused)) *net) { - return nfsd4_umh_cltrack_upcall("init", NULL); + return nfsd4_umh_cltrack_upcall("init", NULL, NULL); } static void @@ -1004,7 +1073,7 @@ nfsd4_umh_cltrack_create(struct nfs4_client *clp) dprintk("%s: can't allocate memory for upcall!\n", __func__); return; } - nfsd4_umh_cltrack_upcall("create", hexid); + nfsd4_umh_cltrack_upcall("create", hexid, NULL); kfree(hexid); } @@ -1018,7 +1087,7 @@ nfsd4_umh_cltrack_remove(struct nfs4_client *clp) dprintk("%s: can't allocate memory for upcall!\n", __func__); return; } - nfsd4_umh_cltrack_upcall("remove", hexid); + nfsd4_umh_cltrack_upcall("remove", hexid, NULL); kfree(hexid); } @@ -1026,14 +1095,16 @@ static int nfsd4_umh_cltrack_check(struct nfs4_client *clp) { int ret; - char *hexid; + char *hexid, *legacy; hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len); if (!hexid) { dprintk("%s: can't allocate memory for upcall!\n", __func__); return -ENOMEM; } - ret = nfsd4_umh_cltrack_upcall("check", hexid); + legacy = nfsd4_cltrack_legacy_recdir(clp->cl_recdir); + ret = nfsd4_umh_cltrack_upcall("check", hexid, legacy); + kfree(legacy); kfree(hexid); return ret; } @@ -1042,10 +1113,13 @@ static void nfsd4_umh_cltrack_grace_done(struct net __attribute__((unused)) *net, time_t boot_time) { + char *legacy; char timestr[22]; /* FIXME: better way to determine max size? */ sprintf(timestr, "%ld", boot_time); - nfsd4_umh_cltrack_upcall("gracedone", timestr); + legacy = nfsd4_cltrack_legacy_topdir(); + nfsd4_umh_cltrack_upcall("gracedone", timestr, legacy); + kfree(legacy); } static struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {