Existem pelo menos duas tarefas do Upstart que afetam o estado sem fio padrão:
-
/etc/init/rfkill-restore.conf
restaura o estado do bloco flexível de todos os rádios para o que eles estavam no último desligamento, conforme registrado em/var/lib/rfkill/saved-state
. -
/etc/init/network-manager.conf
inicia o Network Manager, que por sua vez restaura sua ideia de estado wireless de/var/lib/NetworkManager/NetworkManager.state
.
Se você olhar para essas duas configurações de trabalho, descobrirá que elas não têm nenhum relacionamento temporal, o que parece uma falha de design para mim. Eu estou supondo que esta condição de corrida raramente é um problema porque /etc/init/rfkill-restore.conf
é muito mais simples e tem menos condições de início.
Todas as soluções para impor um padrão sem fio que eu vi tentam usar /etc/rc.local
, incluindo o "moderno" solução que @Lekensteyn e @ rubo77 veio com. Infelizmente, essa solução não funciona para mim em nenhum dos dois laptops que tentei. Isso não é particularmente surpreendente porque /etc/rc.local
também tem nenhum relacionamento temporal que eu posso encontrar em /etc/init/rfkill-restore.conf
e /etc/init/network-manager.conf
. Jogar em um sono demorado em /etc/rc.local
antes de emitir um rfkill block wifi
é uma solução feia para essa bagunça de condição de corrida, mas funciona se o atraso for longo o suficiente.
Uma solução melhor seria impor nossos estados desejados em /var/lib/rfkill/saved-state
e /var/lib/NetworkManager/NetworkManager.state
antes que esses dois trabalhos de Upstart tenham permissão para executar. Podemos conseguir isso criando nosso próprio trabalho Upstart. Na verdade, precisaremos de dois arquivos de configuração de trabalho para alcançar o tempo necessário.
Nossa primeira configuração de trabalho faz as modificações reais do arquivo que precisamos. Ele será executado o mais cedo possível e só será executado uma vez. Crie /etc/init/radio-silence.conf
com este conteúdo:
# radio-silence - Ensure radio silence on startup
#
# Override default startup behaviour of radios to ensure they are all
# disabled until the user deliberately enables them. This job requires
# radio-silence-wait to delay start of any services that may depend on
# resources manipulated by this job.
description "Disable all radios by default"
start on local-filesystems
pre-start script
sed -i -re "s/^(.+[[:space:]]+)[01][[:space:]]*\$//" /var/lib/rfkill/saved-state
sed -i -re "s/^(WirelessEnabled=).*\$/false/" /var/lib/NetworkManager/NetworkManager.state
end script
Como eu prefiro o silêncio total do rádio quando meu laptop começa, eu bloqueio soft todos rádios, não apenas sem fio, mas você pode modificar o primeiro sed
acima para limitar o impacto do trabalho a qualquer dispositivos sem fio que você deseja bloquear soft.
Nossa segunda configuração de trabalho é responsável por garantir que nenhum dos trabalhos rfkill-restore
e network-manager
inicie antes que radio-silence
tenha concluído as modificações do arquivo. Crie /etc/init/radio-silence-wait.conf
da seguinte forma:
# radio-silence-wait - Helper task for radio-silence
#
# Delays the start of all jobs that may depend on resources manipulated
# by radio-silence job. Avoids the need to modify job configuration of
# those other jobs.
description "Assist radio-silence by delaying jobs it affects"
start on (starting rfkill-restore or starting network-manager)
stop on (started radio-silence or stopped radio-silence)
instance $JOB
normal exit 0 2
task
script
status radio-silence | grep -q "start/running" && exit 0
start radio-silence || true
sleep infinity
end script
Com esta solução, não vejo mais problemas de condição de corrida, embora não tenha abordado a corrida teórica entre rfkill-restore
e network-manager
.
Para mais detalhes sobre como esses trabalhos funcionam juntos para atingir nosso objetivo temporal, consulte minha pergunta e resposta, " Como faço para criar uma tarefa de início único de execução garantida para concluir antes de começarem duas outras tarefas? "