Server em execução no kernel do Linux. Deve ouvir acontecer em um segmento ou não?

StackOverflow https://stackoverflow.com/questions/615483

  •  03-07-2019
  •  | 
  •  

Pergunta

Estou escrevendo um cliente / servidor no Linux kernel (Sim. Dentro do kernel. Sua decisão de projeto tomadas e finalizadas. A sua não vai mudar)

O servidor lê os pacotes de entrada de um socket raw. O protocolo de transporte para estes pacotes (na qual o encaixe bruto é escuta) é costume e UDP semelhantes. Em suma, eu não tenho que escutar para conexões de entrada e depois desembolsar um thread para lidar com essa conexão.

Eu tenho apenas para processar qualquer datagrama IP vindo em que socket raw. Vou manter a leitura para os pacotes em um loop infinito no soquete cru. No programa equivalente em nível de usuário, eu teria criado um segmento separado e mantido escuta para pacotes de entrada.

Agora, para o servidor nível do kernel, eu tenho dúvidas sobre se devo executá-lo em um segmento separado ou não, porque:

  1. Eu acho que read () é uma operação de I / O. Então, em algum lugar dentro do read (), kernel deve estar chamando a função de programação () para abrir mão do controle do processador. Assim, depois de chamar read () no socket raw, o contexto ativo kernel atual será colocada em espera (colocar em uma fila de sono, talvez?), Até que os pacotes estão disponíveis. Como e quando os pacotes chegarão, o kernel interrupção contexto será sinal de que o contexto de leitura, que está dormindo na fila, é mais uma vez pronto para ser executado. Eu estou usando 'contexto' aqui de propósito em vez de 'fio'. Assim eu não deveria exigir uma thread do kernel separado.

  2. Por outro lado, se read () não abrir mão do controle, em seguida, toda kernel será bloqueado.

Alguém pode dar dicas sobre como eu deve projetar o meu servidor? Qual é a falácia do argumento apresentado no ponto 1?

Foi útil?

Solução

Eu não tenho certeza se você precisa de um socket raw em tudo no kernel. Dentro do kernel que você pode adicionar um gancho netfilter, ou registar-se outra coisa (???) que irá receber todos os pacotes; este pode ser o que quiser.

Se você usou um socket raw dentro do kernel, então você provavelmente precisará ter uma thread do kernel (ou seja, começou por kernel_thread) para chamar read () nele. Mas não precisa ser um thread do kernel, pode ser um fio userspace que acaba de fazer uma syscall ou dispositivo de chamada especial para chamar a rotina de modo kernel desejado.

Se você tem um gancho registrado, o contexto é chamado em é provavelmente algo que não deve fazer muito processamento; Eu não sei exatamente o que é provável que seja, pode ser um "meio manipulador de fundo" ou "tasklet", qualquer que seja o são (estes tipos de estruturas de controle sempre a mudar de uma versão para outra). Espero que isso não é realmente uma rotina de serviço de interrupção.


Em resposta à sua pergunta original:

  1. Sim, sys_read irá bloquear o segmento de chamada, quer se trate de uma thread do kernel ou um espaço do usuário. O sistema não irá travar. No entanto, se o segmento de chamada não está em um estado onde o bloqueio faz sentido, o kernel irá entrar em pânico (agendamento na interrupção ou algo assim)

Sim, você vai precisar fazer isso em um segmento separado, não, não irá travar o sistema. No entanto, fazer chamadas de sistema em modo kernel é muito duvidoso, embora ela não funciona (tipo de).

Mas se você tiver instalado algum tipo de gancho em vez disso, você não precisa fazer nada disso.

Outras dicas

Eu acho que sua melhor aposta pode ser para emular o modo drivers são escritos, pense em seu servidor como um dispositivo virtual sentado em cima dos que os pedidos são provenientes. Exemplo:. Um driver de mouse aceita entrada contínua, mas não bloquear o sistema se programado corretamente, e um adaptador de rede é provavelmente mais semelhante ao seu caso

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top