Entendemos o comportamento do COW após um fork (como por exemplo descrito aqui ) da seguinte forma: fork cria uma cópia da tabela de páginas do pai para o filho e marca as páginas físicas como somente leitura, portanto, se qualquer um dos dois processos tentar escrevê-lo, acionar uma falha de página e copiar a página.
O que acontece depois que os execs do processo filho? Assumimos que o processo pai pode gravar novamente em suas páginas sem acionar uma falha de página, mas foi difícil encontrar informações exatas sobre como isso é implementado.
Quaisquer ponteiros (incluindo código) são bem-vindos!
Quando o processo filho é executado, todas as suas páginas atuais são substituídas por um novo conjunto de páginas correspondente à nova imagem executável (mais heap, pilha, etc.).
Os sistemas operacionais modernos implementam o CoW mantendo uma contagem de referência para as páginas físicas compartilhadas entre os processos pai e filho. Se uma página for compartilhada entre pai e filho, a contagem de referência será 2. Uma vez que o processo filho passa por exec, a contagem de referência para as páginas compartilhadas é decrementada (por exemplo, volta a 1), portanto, qualquer operação de gravação pelo processo pai terá sucesso sem CoW.
Para sua diversão, crie um programa simples que faça o fork seguido pelo processo filho dormindo por alguns segundos e depois fazendo e exec. Agora observe o conteúdo de
/proc/PID/smaps
ambos os processos antes do fork (único pai, é claro), depois do fork, mas antes do exec e depois do exec. Preste atenção nas páginas Shared_XXX e nos intervalos de endereços correspondentes.Em termos de código, existem algumas extensões XV6 simples para suportar copy-on-write. Uma simples pesquisa no Google pode ser suficiente. Outro lugar para olhar pode ser https://github.com/torvalds/linux/blob/master/kernel/fork.c . Comece a rastreá-lo a partir da entrada do garfo e divirta-se.