aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-11-12 15:00:50 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-11-12 18:55:10 -0500
commitf3aa7e24c91ee3fd387150c2c5a9934b09f44ec5 (patch)
tree9225eeb1ab4c1fa1282fdf73857f969ea3ea7594 /fs
parent2d77bf0a55d64559adb2d48a37bc7e876d6adc11 (diff)
nfsd: pass info about the legacy recoverydir in environment variables
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 <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4recover.c90
1 files changed, 82 insertions, 8 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index e71f713bd7c..38af6155689 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -933,10 +933,75 @@ module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
933 S_IRUGO|S_IWUSR); 933 S_IRUGO|S_IWUSR);
934MODULE_PARM_DESC(cltrack_prog, "Path to the nfsdcltrack upcall program"); 934MODULE_PARM_DESC(cltrack_prog, "Path to the nfsdcltrack upcall program");
935 935
936static bool cltrack_legacy_disable;
937module_param(cltrack_legacy_disable, bool, S_IRUGO|S_IWUSR);
938MODULE_PARM_DESC(cltrack_legacy_disable,
939 "Disable legacy recoverydir conversion. Default: false");
940
941#define LEGACY_TOPDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_TOPDIR="
942#define LEGACY_RECDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_RECDIR="
943
944static char *
945nfsd4_cltrack_legacy_topdir(void)
946{
947 int copied;
948 size_t len;
949 char *result;
950
951 if (cltrack_legacy_disable)
952 return NULL;
953
954 len = strlen(LEGACY_TOPDIR_ENV_PREFIX) +
955 strlen(nfs4_recoverydir()) + 1;
956
957 result = kmalloc(len, GFP_KERNEL);
958 if (!result)
959 return result;
960
961 copied = snprintf(result, len, LEGACY_TOPDIR_ENV_PREFIX "%s",
962 nfs4_recoverydir());
963 if (copied >= len) {
964 /* just return nothing if output was truncated */
965 kfree(result);
966 return NULL;
967 }
968
969 return result;
970}
971
972static char *
973nfsd4_cltrack_legacy_recdir(const char *recdir)
974{
975 int copied;
976 size_t len;
977 char *result;
978
979 if (cltrack_legacy_disable)
980 return NULL;
981
982 /* +1 is for '/' between "topdir" and "recdir" */
983 len = strlen(LEGACY_RECDIR_ENV_PREFIX) +
984 strlen(nfs4_recoverydir()) + 1 + HEXDIR_LEN;
985
986 result = kmalloc(len, GFP_KERNEL);
987 if (!result)
988 return result;
989
990 copied = snprintf(result, len, LEGACY_RECDIR_ENV_PREFIX "%s/%s",
991 nfs4_recoverydir(), recdir);
992 if (copied >= len) {
993 /* just return nothing if output was truncated */
994 kfree(result);
995 return NULL;
996 }
997
998 return result;
999}
1000
936static int 1001static int
937nfsd4_umh_cltrack_upcall(char *cmd, char *arg) 1002nfsd4_umh_cltrack_upcall(char *cmd, char *arg, char *legacy)
938{ 1003{
939 char *envp[] = { NULL }; 1004 char *envp[2];
940 char *argv[4]; 1005 char *argv[4];
941 int ret; 1006 int ret;
942 1007
@@ -947,6 +1012,10 @@ nfsd4_umh_cltrack_upcall(char *cmd, char *arg)
947 1012
948 dprintk("%s: cmd: %s\n", __func__, cmd); 1013 dprintk("%s: cmd: %s\n", __func__, cmd);
949 dprintk("%s: arg: %s\n", __func__, arg ? arg : "(null)"); 1014 dprintk("%s: arg: %s\n", __func__, arg ? arg : "(null)");
1015 dprintk("%s: legacy: %s\n", __func__, legacy ? legacy : "(null)");
1016
1017 envp[0] = legacy;
1018 envp[1] = NULL;
950 1019
951 argv[0] = (char *)cltrack_prog; 1020 argv[0] = (char *)cltrack_prog;
952 argv[1] = cmd; 1021 argv[1] = cmd;
@@ -992,7 +1061,7 @@ bin_to_hex_dup(const unsigned char *src, int srclen)
992static int 1061static int
993nfsd4_umh_cltrack_init(struct net __attribute__((unused)) *net) 1062nfsd4_umh_cltrack_init(struct net __attribute__((unused)) *net)
994{ 1063{
995 return nfsd4_umh_cltrack_upcall("init", NULL); 1064 return nfsd4_umh_cltrack_upcall("init", NULL, NULL);
996} 1065}
997 1066
998static void 1067static void
@@ -1005,7 +1074,7 @@ nfsd4_umh_cltrack_create(struct nfs4_client *clp)
1005 dprintk("%s: can't allocate memory for upcall!\n", __func__); 1074 dprintk("%s: can't allocate memory for upcall!\n", __func__);
1006 return; 1075 return;
1007 } 1076 }
1008 nfsd4_umh_cltrack_upcall("create", hexid); 1077 nfsd4_umh_cltrack_upcall("create", hexid, NULL);
1009 kfree(hexid); 1078 kfree(hexid);
1010} 1079}
1011 1080
@@ -1019,7 +1088,7 @@ nfsd4_umh_cltrack_remove(struct nfs4_client *clp)
1019 dprintk("%s: can't allocate memory for upcall!\n", __func__); 1088 dprintk("%s: can't allocate memory for upcall!\n", __func__);
1020 return; 1089 return;
1021 } 1090 }
1022 nfsd4_umh_cltrack_upcall("remove", hexid); 1091 nfsd4_umh_cltrack_upcall("remove", hexid, NULL);
1023 kfree(hexid); 1092 kfree(hexid);
1024} 1093}
1025 1094
@@ -1027,14 +1096,16 @@ static int
1027nfsd4_umh_cltrack_check(struct nfs4_client *clp) 1096nfsd4_umh_cltrack_check(struct nfs4_client *clp)
1028{ 1097{
1029 int ret; 1098 int ret;
1030 char *hexid; 1099 char *hexid, *legacy;
1031 1100
1032 hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len); 1101 hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len);
1033 if (!hexid) { 1102 if (!hexid) {
1034 dprintk("%s: can't allocate memory for upcall!\n", __func__); 1103 dprintk("%s: can't allocate memory for upcall!\n", __func__);
1035 return -ENOMEM; 1104 return -ENOMEM;
1036 } 1105 }
1037 ret = nfsd4_umh_cltrack_upcall("check", hexid); 1106 legacy = nfsd4_cltrack_legacy_recdir(clp->cl_recdir);
1107 ret = nfsd4_umh_cltrack_upcall("check", hexid, legacy);
1108 kfree(legacy);
1038 kfree(hexid); 1109 kfree(hexid);
1039 return ret; 1110 return ret;
1040} 1111}
@@ -1043,10 +1114,13 @@ static void
1043nfsd4_umh_cltrack_grace_done(struct net __attribute__((unused)) *net, 1114nfsd4_umh_cltrack_grace_done(struct net __attribute__((unused)) *net,
1044 time_t boot_time) 1115 time_t boot_time)
1045{ 1116{
1117 char *legacy;
1046 char timestr[22]; /* FIXME: better way to determine max size? */ 1118 char timestr[22]; /* FIXME: better way to determine max size? */
1047 1119
1048 sprintf(timestr, "%ld", boot_time); 1120 sprintf(timestr, "%ld", boot_time);
1049 nfsd4_umh_cltrack_upcall("gracedone", timestr); 1121 legacy = nfsd4_cltrack_legacy_topdir();
1122 nfsd4_umh_cltrack_upcall("gracedone", timestr, legacy);
1123 kfree(legacy);
1050} 1124}
1051 1125
1052static struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = { 1126static struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {