Alunos:
- Leonardo Gibrowski Faé (20280524-8)
- Ricardo Guimarães (20280681-6)
Repositório: https://github.com/Horus645/LabSysOpT1
Essas instruções pressupõem que o usuário já efetuou os passos descritos nos tutoriais 1.1, 1.2 e 1.3, disponibilizados pelo professor. Em particular, o usuário deverá criar uma rota entre a máquina Host e a máquina Guest(QEMU)(testar com o Ping).
Abrindo o menuconfig, defina a seguinte configuração:
-- Target Packeges
-- Interpreter languages and scripting
[*] python3
- O python exige suporte para o WCHAR. Para disponibilizar o mesmo, voce derá mudar a biblioteca do C disponível na distribuição:
-- Toolchain
C library (uClibc-ng) -->
.
.
.
[*] Enable WCHAR support
- Salve as configurações e execute o comando
makeno terminal
- Novamente, abrindo o menuconfig, habilite o
dropbear
-- Target packages
-- Networking applications
[*] dropbear
- Rode o
make - Suba a máquina emulada e configure uma senha com o comando
passwd(pode ser vazia) - Abra um novo terminal na máquina Host e tente conectar via SSH na Guest com o comando:
ssh root@<IP da Guest> - Para descobrir o IP da máquina Guest, execute o comando
ifconfigdentro dela(IPv4 da interface eth0) - Para sair da sessão SSH, utilize Ctrl+d.
Primeiramente, edite a variável HOST_NAME dentro do arquivo web_server.py para o número de IP da máquina target.
- Execute o utilitário
scpda máquina Host para transferir o arquivo contendo o código gerador do servidor HTTP(no caso, web_server.py):
scp web_server.py root@<IP Do Host>:/root/
- OBS: Caso o comando falhe(é possível que aconteça por incompatibilidade de versão), adicione a flag -O para utilizar o protocolo legado.
Entre na máquina target e execute o script:
python web_server.py
A página estará disponível no endereço <IP do Target>:8000. Você pode acessá-la usando um browser qualquer.
screenshot.png tem um exemplo de como a página será apresentada.
Tirando a data e hora, todas as informações da página são geradas lendo as informações do pseudo sistema de arquivos /proc.
Data e hora são adquiridas com o comando date:
def date_time():
return os.popen("date").read()Uptime foi calculado a partir de /proc/uptime:
def uptime():
s = read_file("/proc/uptime")
total_seconds = float(s.split(' ')[0])
return time_from_seconds(total_seconds)As informações de cpu foram retiradas de /proc/cpuinfo:
def procinfo():
lines = read_file("/proc/cpuinfo").split('\n')
ret = "<br>"
for line in lines:
words = line.split(':')
key = words[0].strip()
value = words[1].strip()
if key == "vendor_id" or \
key == "cpu family" or \
key == "model" or \
key == "model name":
ret += HTML_INDENT + key + ": " + value + "<br>"
elif key == "cpu MHz":
ret += HTML_INDENT + key + ": " + value + "<br>"
break
return retDados de memória foram lidos de /proc/meminfo, e os cálculos de uso são os mesmos que os que estão documentados em man free.
def mem():
"For this function, we follow the same calculations as the `free` command"
lines = read_file("/proc/meminfo").split('\n')
# MemTotal
for s in lines[0].split(' '):
if s.isnumeric():
total = int(s)
break
# MemFree
for s in lines[1].split(' '):
if s.isnumeric():
free = int(s)
break
# Buffers
for s in lines[3].split(' '):
if s.isnumeric():
buffers = int(s)
break
# Cached
for s in lines[4].split(' '):
if s.isnumeric():
cache = int(s)
break
# SReclaimable
for s in lines[27].split(' '):
if s.isnumeric():
cache += int(s)
break
used = total - free - buffers - cache
return "Total: " + str(total) + "Kb, Used: " + str(used) + "Kb"A versão do sistema foi colhida de /proc/version:
def sysversion():
return read_file("/proc/version")Os PIDs e os nomes dos processos sendo executados na máquina correspondem aos diretórios numerados localizados em /proc. Dentro de cada um desses diretórios, há um arquivo stat, cuja primeira palavra é o PID e a segunda é o comando, entre parênteses:
def proc_list():
ret = "<br>" + HTML_INDENT + "Pid Name<br>"
for dir_entry in os.listdir("/proc"):
if dir_entry.isnumeric():
s = read_file("/proc/" + dir_entry + "/stat")
pid = s.split(' ')[0]
name = s.split(' ')[1].strip("()")
ret += HTML_INDENT + pid + " " + name + "<br>"
return retO uso de cpu é mensurado através dos dados em /proc/stat. A documentação encontrada em man proc explica que os valores em /proc/stat correspondem ao tempo que o cpu permaneceu em cada um de seus estados (includindo idle). Usando essas informações, podemos calcular o percentual de tempo em que a cpu ficou ocupada. /proc/stat contém informações cumulativas desde que o sistema foi inicializado. Isso significa que para calcularmos os valores atuais, precisamos medir em um determinado instante, aguardar, medir novamente, e pegar a diferença entre os valores. No script, nós medimos a primeira vez durante a inicialização, e medimos novamente cada vez que é feita uma requisição da página para o servidor.
def updt_proc_usage() -> float:
global prev_idle
global prev_non_idle
cpustats = read_file("/proc/stat").split('\n')[0].split(' ')[2:]
idle = int(cpustats[3]) + int(cpustats[4]) # idle + iowait
non_idle = int(cpustats[0]) + \
int(cpustats[1]) + \
int(cpustats[2]) + \
int(cpustats[5]) + \
int(cpustats[6]) + \
int(cpustats[7])
prev_total = prev_idle + prev_non_idle
total = idle + non_idle
totald = total - prev_total
idled = idle - prev_idle
cpu_percentage = float(totald - idled) / float(totald)
prev_idle = idle
prev_non_idle = non_idle
return cpu_percentage * 100.0