diff options
author | Tudor Florea <tudor.florea@enea.com> | 2014-10-10 03:20:04 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2014-10-10 03:20:04 +0200 |
commit | 1b8dfe266937a37a4c642f96ceb2347bf4c00a17 (patch) | |
tree | 0c6aab146bb3c82efd9c7846a9a4e70dcb0ec84f /meta-networking/recipes-daemons/autofs/autofs-5.0.7/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch | |
download | meta-openembedded-daisy-140929.tar.gz |
initial commit for Enea Linux 4.0-140929daisy-140929
Migrated from the internal git server on the daisy-enea-point-release branch
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'meta-networking/recipes-daemons/autofs/autofs-5.0.7/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch')
-rw-r--r-- | meta-networking/recipes-daemons/autofs/autofs-5.0.7/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/meta-networking/recipes-daemons/autofs/autofs-5.0.7/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch b/meta-networking/recipes-daemons/autofs/autofs-5.0.7/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch new file mode 100644 index 0000000000..8ce6c0f9e3 --- /dev/null +++ b/meta-networking/recipes-daemons/autofs/autofs-5.0.7/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch | |||
@@ -0,0 +1,179 @@ | |||
1 | autofs-5.0.7 - fix file descriptor leak when reloading the daemon | ||
2 | |||
3 | From: Leonardo Chiquitto <leonardo.lists@gmail.com> | ||
4 | |||
5 | A customer reported that AutoFS may leak file descriptors when some | ||
6 | maps are modified and the daemon reloaded. I'm able to reproduce the | ||
7 | problem on 5.0.7 by following these steps: | ||
8 | |||
9 | 1. Configure a simple direct mount: | ||
10 | |||
11 | # cat /etc/auto.master | ||
12 | /- /etc/auto.direct | ||
13 | |||
14 | # cat /etc/auto.direct | ||
15 | /nfs server:/nfs | ||
16 | |||
17 | 2. Start the automounter and do NOT trigger the mount | ||
18 | |||
19 | 3. Replace /etc/auto.direct with: | ||
20 | |||
21 | # cat /etc/auto.direct | ||
22 | /nfs/1 server:/nfs | ||
23 | /nfs/2 server:/nfs | ||
24 | |||
25 | 4. Reload: | ||
26 | |||
27 | # kill -HUP $(pidof automount) | ||
28 | |||
29 | >From now on, every reload will leak a file descriptor: | ||
30 | |||
31 | # ls -la /proc/$(pidof automount)/fd | grep /nfs | ||
32 | lr-x------ 1 root root 64 Aug 14 22:08 11 -> /nfs | ||
33 | lr-x------ 1 root root 64 Aug 14 22:08 12 -> /nfs | ||
34 | lr-x------ 1 root root 64 Aug 14 22:08 13 -> /nfs | ||
35 | lr-x------ 1 root root 64 Aug 14 22:08 14 -> /nfs | ||
36 | lr-x------ 1 root root 64 Aug 14 22:08 5 -> /nfs | ||
37 | |||
38 | I've investigated the problem and discovered that the leak happens in | ||
39 | do_umount_autofs_direct(): | ||
40 | |||
41 | - edit imk | ||
42 | The same leak is present in umount_autofs_offset() also. | ||
43 | Updated patch to cover that too. | ||
44 | - end edit | ||
45 | |||
46 | int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list | ||
47 | *mnts, struct mapent *me) | ||
48 | { | ||
49 | (...) | ||
50 | if (me->ioctlfd != -1) { | ||
51 | if (tree_is_mounted(mnts, me->key, MNTS_REAL)) { | ||
52 | error(ap->logopt, | ||
53 | "attempt to umount busy direct mount %s", | ||
54 | me->key); | ||
55 | return 1; | ||
56 | } | ||
57 | ioctlfd = me->ioctlfd; | ||
58 | } else // ioctlfd == -1 | ||
59 | ops->open(ap->logopt, &ioctlfd, me->dev, me->key); <= we open it here | ||
60 | |||
61 | if (ioctlfd >= 0) { | ||
62 | unsigned int status = 1; | ||
63 | |||
64 | rv = ops->askumount(ap->logopt, ioctlfd, &status); | ||
65 | /// at this point, rv == 0 and status == 0 | ||
66 | if (rv) { | ||
67 | char *estr = strerror_r(errno, buf, MAX_ERR_BUF); | ||
68 | error(ap->logopt, "ioctl failed: %s", estr); | ||
69 | return 1; | ||
70 | } else if (!status) { | ||
71 | /// at this point, ap->state == ST_READMAP | ||
72 | if (ap->state != ST_SHUTDOWN_FORCE) { | ||
73 | error(ap->logopt, | ||
74 | "ask umount returned busy for %s", | ||
75 | me->key); | ||
76 | return 1; <= we return here, without closing the fd | ||
77 | } else { | ||
78 | me->ioctlfd = -1; | ||
79 | ops->catatonic(ap->logopt, ioctlfd); | ||
80 | ops->close(ap->logopt, ioctlfd); | ||
81 | goto force_umount; | ||
82 | } | ||
83 | (...) | ||
84 | --- | ||
85 | CHANGELOG | 1 + | ||
86 | daemon/direct.c | 19 ++++++++++++++++--- | ||
87 | 2 files changed, 17 insertions(+), 3 deletions(-) | ||
88 | |||
89 | diff --git a/CHANGELOG b/CHANGELOG | ||
90 | index 46ef335..a7ed212 100644 | ||
91 | --- a/CHANGELOG | ||
92 | +++ b/CHANGELOG | ||
93 | @@ -30,6 +30,7 @@ | ||
94 | - workaround missing GNU versionsort extension. | ||
95 | - dont fail on master map self include. | ||
96 | - fix wildcard multi map regression. | ||
97 | +- fix file descriptor leak when reloading the daemon. | ||
98 | |||
99 | 25/07/2012 autofs-5.0.7 | ||
100 | ======================= | ||
101 | diff --git a/daemon/direct.c b/daemon/direct.c | ||
102 | index 3e09c5d..228a666 100644 | ||
103 | --- a/daemon/direct.c | ||
104 | +++ b/daemon/direct.c | ||
105 | @@ -86,7 +86,8 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru | ||
106 | { | ||
107 | struct ioctl_ops *ops = get_ioctl_ops(); | ||
108 | char buf[MAX_ERR_BUF]; | ||
109 | - int ioctlfd, rv, left, retries; | ||
110 | + int ioctlfd = -1, rv, left, retries; | ||
111 | + int opened = 0; | ||
112 | |||
113 | left = umount_multi(ap, me->key, 0); | ||
114 | if (left) { | ||
115 | @@ -103,8 +104,10 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru | ||
116 | return 1; | ||
117 | } | ||
118 | ioctlfd = me->ioctlfd; | ||
119 | - } else | ||
120 | + } else { | ||
121 | ops->open(ap->logopt, &ioctlfd, me->dev, me->key); | ||
122 | + opened = 1; | ||
123 | + } | ||
124 | |||
125 | if (ioctlfd >= 0) { | ||
126 | unsigned int status = 1; | ||
127 | @@ -113,12 +116,16 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru | ||
128 | if (rv) { | ||
129 | char *estr = strerror_r(errno, buf, MAX_ERR_BUF); | ||
130 | error(ap->logopt, "ioctl failed: %s", estr); | ||
131 | + if (opened && ioctlfd != -1) | ||
132 | + ops->close(ap->logopt, ioctlfd); | ||
133 | return 1; | ||
134 | } else if (!status) { | ||
135 | if (ap->state != ST_SHUTDOWN_FORCE) { | ||
136 | error(ap->logopt, | ||
137 | "ask umount returned busy for %s", | ||
138 | me->key); | ||
139 | + if (opened && ioctlfd != -1) | ||
140 | + ops->close(ap->logopt, ioctlfd); | ||
141 | return 1; | ||
142 | } else { | ||
143 | me->ioctlfd = -1; | ||
144 | @@ -536,7 +543,8 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) | ||
145 | { | ||
146 | struct ioctl_ops *ops = get_ioctl_ops(); | ||
147 | char buf[MAX_ERR_BUF]; | ||
148 | - int ioctlfd, rv = 1, retries; | ||
149 | + int ioctlfd = -1, rv = 1, retries; | ||
150 | + int opened = 0; | ||
151 | |||
152 | if (me->ioctlfd != -1) { | ||
153 | if (is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) { | ||
154 | @@ -554,6 +562,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) | ||
155 | return 0; | ||
156 | } | ||
157 | ops->open(ap->logopt, &ioctlfd, me->dev, me->key); | ||
158 | + opened = 1; | ||
159 | } | ||
160 | |||
161 | if (ioctlfd >= 0) { | ||
162 | @@ -563,6 +572,8 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) | ||
163 | if (rv) { | ||
164 | char *estr = strerror_r(errno, buf, MAX_ERR_BUF); | ||
165 | logerr("ioctl failed: %s", estr); | ||
166 | + if (opened && ioctlfd != -1) | ||
167 | + ops->close(ap->logopt, ioctlfd); | ||
168 | return 1; | ||
169 | } else if (!status) { | ||
170 | if (ap->state != ST_SHUTDOWN_FORCE) { | ||
171 | @@ -570,6 +581,8 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) | ||
172 | error(ap->logopt, | ||
173 | "ask umount returned busy for %s", | ||
174 | me->key); | ||
175 | + if (opened && ioctlfd != -1) | ||
176 | + ops->close(ap->logopt, ioctlfd); | ||
177 | return 1; | ||
178 | } else { | ||
179 | me->ioctlfd = -1; | ||