mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-20 22:01:31 +00:00
This patch fixes a bug in aufs that can cause docker processes to enter a defunct state but still consume 100% cpu. The processes are unkillable as is the entire docker container, with the only recourse being to reboot the machine. The problem was reported to Debian in the following report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=812207 Message #47 in that exchange contains two patches which resolve the problem, and this commit is the simple combination of those two.
134 lines
3.2 KiB
Diff
134 lines
3.2 KiB
Diff
*** a/fs/aufs/xino.c 2017-09-20 14:25:41.841850111 +0000
|
|
--- b/fs/aufs/xino.c 2017-09-20 19:23:31.065603010 +0000
|
|
*************** ssize_t xino_fread(au_readf_t func, stru
|
|
*** 53,58 ****
|
|
--- 53,61 ----
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
+ static ssize_t xino_fwrite_wkq(au_writef_t func, struct file *file, void *buf,
|
|
+ size_t size, loff_t *pos);
|
|
+
|
|
static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
|
|
size_t size, loff_t *pos)
|
|
{
|
|
*************** static ssize_t do_xino_fwrite(au_writef_
|
|
*** 63,75 ****
|
|
const char __user *u;
|
|
} buf;
|
|
|
|
buf.k = kbuf;
|
|
oldfs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
do {
|
|
- /* todo: signal_pending? */
|
|
err = func(file, buf.u, size, pos);
|
|
! } while (err == -EAGAIN || err == -EINTR);
|
|
set_fs(oldfs);
|
|
|
|
#if 0 /* reserved for future use */
|
|
--- 66,92 ----
|
|
const char __user *u;
|
|
} buf;
|
|
|
|
+ int i;
|
|
+ const int prevent_endless = 10;
|
|
+
|
|
+ i = 0;
|
|
buf.k = kbuf;
|
|
oldfs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
do {
|
|
err = func(file, buf.u, size, pos);
|
|
! if (err == -EINTR
|
|
! && !au_wkq_test()
|
|
! && fatal_signal_pending(current)) {
|
|
! set_fs(oldfs);
|
|
! err = xino_fwrite_wkq(func, file, kbuf, size, pos);
|
|
! BUG_ON(err == -EINTR);
|
|
! oldfs = get_fs();
|
|
! set_fs(KERNEL_DS);
|
|
! }
|
|
! } while (i++ < prevent_endless &&
|
|
! (err == -EAGAIN || err == -EINTR));
|
|
!
|
|
set_fs(oldfs);
|
|
|
|
#if 0 /* reserved for future use */
|
|
*************** ssize_t xino_fwrite(au_writef_t func, st
|
|
*** 100,132 ****
|
|
{
|
|
ssize_t err;
|
|
|
|
- /* todo: signal block and no wkq? */
|
|
if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
|
|
lockdep_off();
|
|
err = do_xino_fwrite(func, file, buf, size, pos);
|
|
lockdep_on();
|
|
} else {
|
|
! /*
|
|
! * it breaks RLIMIT_FSIZE and normal user's limit,
|
|
! * users should care about quota and real 'filesystem full.'
|
|
! */
|
|
! int wkq_err;
|
|
! struct do_xino_fwrite_args args = {
|
|
! .errp = &err,
|
|
! .func = func,
|
|
! .file = file,
|
|
! .buf = buf,
|
|
! .size = size,
|
|
! .pos = pos
|
|
! };
|
|
!
|
|
! wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
|
|
! if (unlikely(wkq_err))
|
|
! err = wkq_err;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
--- 117,157 ----
|
|
{
|
|
ssize_t err;
|
|
|
|
if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
|
|
lockdep_off();
|
|
err = do_xino_fwrite(func, file, buf, size, pos);
|
|
lockdep_on();
|
|
} else {
|
|
! err = xino_fwrite_wkq(func, file, buf, size, pos);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
+
|
|
+ static ssize_t xino_fwrite_wkq(au_writef_t func, struct file *file, void *buf,
|
|
+ size_t size, loff_t *pos)
|
|
+ {
|
|
+ ssize_t err;
|
|
+ int wkq_err;
|
|
+ struct do_xino_fwrite_args args = {
|
|
+ .errp = &err,
|
|
+ .func = func,
|
|
+ .file = file,
|
|
+ .buf = buf,
|
|
+ .size = size,
|
|
+ .pos = pos
|
|
+ };
|
|
+
|
|
+ /*
|
|
+ * it breaks RLIMIT_FSIZE and normal user's limit,
|
|
+ * users should care about quota and real 'filesystem full.'
|
|
+ */
|
|
+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
|
|
+ if (unlikely(wkq_err))
|
|
+ err = wkq_err;
|
|
+
|
|
+ return err;
|
|
+ }
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|