[lxc-devel] Question on freezer.c

Daniel Lezcano daniel.lezcano at free.fr
Mon Oct 11 07:42:04 UTC 2010


On 10/11/2010 08:48 AM, richard -rw- weinberger wrote:
> Hi list,
>
> I've a question on freezer.c.
> In freeze_unfreeze() is a while(1) loop which write()s "FROZEN" or
> "THAWED" until read() returns the same.
> Why do we need this loop?
> It looks like a hack to me.


The freezer documentation specifies:
  state (because of the cgroup state 'freezeing), making the cgroup to 
converge to the frozen state.

When we check the cgroup is frozen, the kernel look at this task list 
and find the new child process which is not yet frozen and will return 
'freezing' instead of "frozen'. Freezing the cgroup again will freeze 
this missing task.

"It's important to note that freezing can be incomplete. In that case we 
return EBUSY. This means that some tasks in the cgroup are busy doing 
something that prevents us from completely freezing the cgroup at this 
time. After EBUSY, the cgroup will remain partially frozen -- reflected 
by freezer.state reporting "FREEZING" when read. The state will remain 
"FREEZING" until one of these things happens:

  1) Userspace cancels the freezing operation by writing "THAWED" to the 
freezer.state file

  2) Userspace retries the freezing operation by writing "FROZEN" to 
the freezer.state file (writing "FREEZING" is not legal and returns EINVAL)

  3) The tasks that blocked the cgroup from entering the "FROZEN" state 
disappear from the cgroup's set of tasks."

The loop in the code is for the case (2).

Let me clarify:

(1) When we freeze a cgroup, the kernel browse the cgroup's tasks list 
and will send a fake signal to each of them.

But the places where the hooks are in the kernel code (fork and exit), 
make possible to send this signal to a task while it is forking and the 
child process is not yet in the cgroup's task list.

The forking task will go to the frozen state right after returning from 
the fork but the child task won't because it didn't receive the fake signal.

If this child process forks again, the new child will automatically go 
to the frozen state (because of the cgroup state 'freezing), making the 
cgroup to converge to the frozen state.

When we check the cgroup is frozen, the kernel look at this task list 
and find the new child process which is not yet frozen and will return 
'freezing' instead of "frozen'. Freezing the cgroup again will freeze 
this missing task.


(2) It's possible to freeze a cgroup while it is in important IO, aka 
'uninteruptible state', so we won't be able to freeze  immediately and 
we have to retry.



These both cases happen rarely, so most of the time, one iteration in 
the loop is enough to freeze the container.




More information about the lxc-devel mailing list