summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorScott Mayhew <smayhew@redhat.com>2019-03-26 18:06:29 -0400
committerJ. Bruce Fields <bfields@redhat.com>2019-04-24 09:46:34 -0400
commit869216075b63c7a4030ee193c079cb5a69a918cb (patch)
treeb4c4aadfd5f30e1bdc2e802c581fb884f1faefca /fs
parent362063a595be959bc08f4163e6405a0266740091 (diff)
nfsd: re-order client tracking method selection
The new order is first nfsdcld, then the UMH upcall, and finally the legacy tracking method. Added some printk's to the tracking initialization functions so it's clear which tracking method was ultimately selected. Signed-off-by: Scott Mayhew <smayhew@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4recover.c80
1 files changed, 65 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 09e3c9352778..d60001da1dbf 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -628,6 +628,7 @@ nfsd4_legacy_tracking_init(struct net *net)
628 status = nfsd4_load_reboot_recovery_data(net); 628 status = nfsd4_load_reboot_recovery_data(net);
629 if (status) 629 if (status)
630 goto err; 630 goto err;
631 printk("NFSD: Using legacy client tracking operations.\n");
631 return 0; 632 return 0;
632 633
633err: 634err:
@@ -937,7 +938,7 @@ nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
937 938
938/* Initialize rpc_pipefs pipe for communication with client tracking daemon */ 939/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
939static int 940static int
940nfsd4_init_cld_pipe(struct net *net) 941__nfsd4_init_cld_pipe(struct net *net)
941{ 942{
942 int ret; 943 int ret;
943 struct dentry *dentry; 944 struct dentry *dentry;
@@ -980,6 +981,17 @@ err:
980 return ret; 981 return ret;
981} 982}
982 983
984static int
985nfsd4_init_cld_pipe(struct net *net)
986{
987 int status;
988
989 status = __nfsd4_init_cld_pipe(net);
990 if (!status)
991 printk("NFSD: Using old nfsdcld client tracking operations.\n");
992 return status;
993}
994
983static void 995static void
984nfsd4_remove_cld_pipe(struct net *net) 996nfsd4_remove_cld_pipe(struct net *net)
985{ 997{
@@ -1285,27 +1297,55 @@ nfs4_cld_state_shutdown(struct net *net)
1285 kfree(nn->reclaim_str_hashtbl); 1297 kfree(nn->reclaim_str_hashtbl);
1286} 1298}
1287 1299
1300static bool
1301cld_running(struct nfsd_net *nn)
1302{
1303 struct cld_net *cn = nn->cld_net;
1304 struct rpc_pipe *pipe = cn->cn_pipe;
1305
1306 return pipe->nreaders || pipe->nwriters;
1307}
1308
1288static int 1309static int
1289nfsd4_cld_tracking_init(struct net *net) 1310nfsd4_cld_tracking_init(struct net *net)
1290{ 1311{
1291 int status; 1312 int status;
1292 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 1313 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1314 bool running;
1315 int retries = 10;
1293 1316
1294 status = nfs4_cld_state_init(net); 1317 status = nfs4_cld_state_init(net);
1295 if (status) 1318 if (status)
1296 return status; 1319 return status;
1297 1320
1298 status = nfsd4_init_cld_pipe(net); 1321 status = __nfsd4_init_cld_pipe(net);
1299 if (status) 1322 if (status)
1300 goto err_shutdown; 1323 goto err_shutdown;
1301 1324
1325 /*
1326 * rpc pipe upcalls take 30 seconds to time out, so we don't want to
1327 * queue an upcall unless we know that nfsdcld is running (because we
1328 * want this to fail fast so that nfsd4_client_tracking_init() can try
1329 * the next client tracking method). nfsdcld should already be running
1330 * before nfsd is started, so the wait here is for nfsdcld to open the
1331 * pipefs file we just created.
1332 */
1333 while (!(running = cld_running(nn)) && retries--)
1334 msleep(100);
1335
1336 if (!running) {
1337 status = -ETIMEDOUT;
1338 goto err_remove;
1339 }
1340
1302 status = nfsd4_cld_grace_start(nn); 1341 status = nfsd4_cld_grace_start(nn);
1303 if (status) { 1342 if (status) {
1304 if (status == -EOPNOTSUPP) 1343 if (status == -EOPNOTSUPP)
1305 printk(KERN_WARNING "NFSD: Please upgrade nfsdcld.\n"); 1344 printk(KERN_WARNING "NFSD: Please upgrade nfsdcld.\n");
1306 nfs4_release_reclaim(nn); 1345 nfs4_release_reclaim(nn);
1307 goto err_remove; 1346 goto err_remove;
1308 } 1347 } else
1348 printk("NFSD: Using nfsdcld client tracking operations.\n");
1309 return 0; 1349 return 0;
1310 1350
1311err_remove: 1351err_remove:
@@ -1552,6 +1592,8 @@ nfsd4_umh_cltrack_init(struct net *net)
1552 1592
1553 ret = nfsd4_umh_cltrack_upcall("init", NULL, grace_start, NULL); 1593 ret = nfsd4_umh_cltrack_upcall("init", NULL, grace_start, NULL);
1554 kfree(grace_start); 1594 kfree(grace_start);
1595 if (!ret)
1596 printk("NFSD: Using UMH upcall client tracking operations.\n");
1555 return ret; 1597 return ret;
1556} 1598}
1557 1599
@@ -1701,9 +1743,20 @@ nfsd4_client_tracking_init(struct net *net)
1701 if (nn->client_tracking_ops) 1743 if (nn->client_tracking_ops)
1702 goto do_init; 1744 goto do_init;
1703 1745
1746 /* First, try to use nfsdcld */
1747 nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
1748 status = nn->client_tracking_ops->init(net);
1749 if (!status)
1750 return status;
1751 if (status != -ETIMEDOUT) {
1752 nn->client_tracking_ops = &nfsd4_cld_tracking_ops_v0;
1753 status = nn->client_tracking_ops->init(net);
1754 if (!status)
1755 return status;
1756 }
1757
1704 /* 1758 /*
1705 * First, try a UMH upcall. It should succeed or fail quickly, so 1759 * Next, try the UMH upcall.
1706 * there's little harm in trying that first.
1707 */ 1760 */
1708 nn->client_tracking_ops = &nfsd4_umh_tracking_ops; 1761 nn->client_tracking_ops = &nfsd4_umh_tracking_ops;
1709 status = nn->client_tracking_ops->init(net); 1762 status = nn->client_tracking_ops->init(net);
@@ -1711,26 +1764,23 @@ nfsd4_client_tracking_init(struct net *net)
1711 return status; 1764 return status;
1712 1765
1713 /* 1766 /*
1714 * See if the recoverydir exists and is a directory. If it is, 1767 * Finally, See if the recoverydir exists and is a directory.
1715 * then use the legacy ops. 1768 * If it is, then use the legacy ops.
1716 */ 1769 */
1717 nn->client_tracking_ops = &nfsd4_legacy_tracking_ops; 1770 nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
1718 status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path); 1771 status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
1719 if (!status) { 1772 if (!status) {
1720 status = d_is_dir(path.dentry); 1773 status = d_is_dir(path.dentry);
1721 path_put(&path); 1774 path_put(&path);
1722 if (status) 1775 if (!status) {
1723 goto do_init; 1776 status = -EINVAL;
1777 goto out;
1778 }
1724 } 1779 }
1725 1780
1726 /* Finally, try to use nfsdcld */
1727 nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
1728 status = nn->client_tracking_ops->init(net);
1729 if (!status)
1730 return status;
1731 nn->client_tracking_ops = &nfsd4_cld_tracking_ops_v0;
1732do_init: 1781do_init:
1733 status = nn->client_tracking_ops->init(net); 1782 status = nn->client_tracking_ops->init(net);
1783out:
1734 if (status) { 1784 if (status) {
1735 printk(KERN_WARNING "NFSD: Unable to initialize client " 1785 printk(KERN_WARNING "NFSD: Unable to initialize client "
1736 "recovery tracking! (%d)\n", status); 1786 "recovery tracking! (%d)\n", status);