sunnuntai 27. marraskuuta 2022

Arch Linux asennus

Arch Linux on muuntautumiskykyinen distro, josta voi rakentaa sellaisen Linuxin kuin haluaa!

Arch Linux asennetaan ajamalla erilaisia apuohjelmia, jotka yksi kerrallaan valmistelevat järjestelmää käyttökuntoon. Alla päivitetty Arch Linuxin asennusohje, joka perustuu vuonna 2015 julkaisemaani Arch Linuxin asennusohjeeseen.

1 Alustus

1.1 Päätin jättää tietokoneeseen pienen osion Windowsia varten, jotta voin tarvittaessa asentaa BIOS-päivitykset valmistajan Windows-ohjelmalla. Tätä varten käynnistin uuden tietokoneen aluksi Windowsiin ja kaivoin esiin vanhan Windows-ohjauspaneelin, joka löytyy myös Windows 11:sta hakusanalla "ohjauspaneeli". Ohjauspaneelista etsi järjestelmä ja klikkaa luo- ja alusta kiintolevyosioita. Ruudulle pitäisi avautua levynhallinta:

Klikkaa hiiren oikeaa nappia C-levyn päällä ja valitse pienennä asema. Syötä numeroina, montako megatavua osiota pienennetään. Esimerkiksi jos haluat jättää Linuxille 880 gigaa levytilaa, niin syötä luku 880000:

1.2 Lataa ja asenna Arch Linuxin asennusmedia USB-tikulle. Itse käytin tähän toista Linux tietokonetta ja 2015 kirjoittamaani ohjetta.

1.3 Käynnistä tietokone ja mene BIOS-asetuksiin painamalla F1, F2 tai delete-näppäintä käynnistyksen jälkeen. Käynnistä tietokone uudelleen, kunnes löydät oikean näppäimen. Kun pääset BIOSiin, niin etsi Secure Boot -ominaisuus ja ota se pois päältä. Aseta tietokonekone käynnistymään ensisijaisesti USB-tikulta.

Tietokone on nyt valmis Linuxin asennukseen!

2 Tietokoneen käynnistys USB-tikulta

2.1 Aseta edellä tekemäsi asennusmedia USB-porttiin ja käynnistä tietokone. Jos BIOS asetukset ovat oikein, niin tietokone käynnistyy USB-tikulta ja ruudulle avautuu komentokehoite.

2.2 Ota käyttöön suomalainen näppäimistö komennolla

loadkeys fi

2.3 Ota käyttöön isompi fontti komennolla

setfont ter-v32n

2.3 Kytke tietokone verkkokaapeliin ja selvitä verkkolaitteen nimi komennolla

ip link

Komento tulostaa esimerkiksi

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP mode DEFAULT group default
    link/ether 88:ae:dd:17:59:4e brd ff:ff:ff:ff:ff:ff
4: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 state DOWN mode DORMANT group default
    link/ether 00:93:37:63:a3:21 brd ff:ff:ff:ff:ff:ff

missä enp3s0 on kaivattu verkkolaitteen nimi.

2.4 Käynnistä DHCP-palvelin verkkolaitteelle komennolla

systemctl start dhcpcd@enp3s0

missä enp3s0 on ip link -kommennon antama verkkolaite. DHCP-palvelin hakee tietokoneelle IP-osoitteen ja avaa tilapäisen verkkoyhteyden muutamassa sekunnissa.

2.5 Tarkista, että verkko toimii esimerkiksi komennolla

ping www.google.fi

Jos ruudulle tulostuu rivejä noin sekunnin välein, niin verkko toimii ja voit jatkaa Linuxin asennusta tai korjausta.

3 Massamuistien osiointi

3.1 Päätä, miten haluat osioida massamuistin.

Omassa koneessani on 16 gigatavua muistia, joten päätin jättää perinteisen sivutusosion (swap) tekemättä. Tästä seuraa, että jos fyysinen muisti ei riitä ohjelmalle, niin ohjelma tai koko Linux saattaa kaatua. Lisäksi päätin sijoittaa kaikki tiedostot samalle osioille, vaikka vaarana onkin, että sähkökatko, muistin loppuminen tai muu odottamaton tietokoneen kaatuminen saattaa rikkoa tiedostojärjestelmän siten, ettei tietokone käynnisty enää ollenkaan.

Sähkökatkoja ja muita kaatumisia on kuitenkin vuosien varrella sattunut useita, eikä tiedostojen jakaminen eri osioille ole pelastanut tilannetta: jos esimerkiksi omalla osiollaan pidetty mysql-tietokanta on mennyt rikki koneen kaatumisen vuoksi, niin koneen käynnistys on pysähtynyt, vaikka kaikki muut osiot ovat olleet ehjiä. Tarvittaessa rikkoontuneet tiedostojärjestelmät on kuitenkin aina saanut pelastettua käynnistämällä koneen uudestaan USB-tikulta, joten koneen kaatuminen ei huoleta. Tarvittaessa saan palautettua tärkeimmät tiedostot varmuuskopioista.

Päätin myös salata Linux-osion samalla tavalla kuin tekisin kannettavalle tietokoneelle. Salaus vaikeuttaa rikkoontuneen tiedostojärjestelmän pelastamista, koska salaus pitää ensin avata ennen kuin tiedostojärjestelmää pääsee näkemään tai korjaamaan, mutta tämäkään ei huoleta minua.

3.2 Selvitä osioitavien massamuistien laitenimet komennolla

lsblk

Komento tulostaa esimerkiksi

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0         7:0    0   671M  1 loop /run/archiso/airootfs
sda           8:0    1   3.7G  0 disk
├─sda1        8:1    1   767M  0 part
└─sda2        8:2    1    15M  0 part
nvme0n1     259:0    0 953.9G  0 disk
├─nvme0n1p1 259:1    0   260M  0 part
├─nvme0n1p2 259:2    0    16M  0 part
├─nvme0n1p3 259:3    0  92.3G  0 part
└─nvme0n1p4 259:4    0     2G  0 part

Tulosteesta voidaan lukea, että laitteeseen on kytketty 3,7 gigatavun massamuisti laitenimellä sda ja 953,9 gigatavun massamuisti laitenimellä nvme0n1. Molemmat massamuistit on edelleen osioitu.

3.3 Käynnistä parted ohjelma massamuistin osiointia varten komennolla

parted /dev/nvme0n1

missä nvme0n1 on lsblk komennon tulosteesta poimittu massamuistin laitenimi.

Tulosta nykyinen osiointitaulu gpartedissa komennoilla

unit mb print free

Komento antaa listan varatuista osioista sekä niiden välissä olevasta tyhjästä tilasta esimerkiksi

Model: SAMSUNG MZVL21T0HCLR-00BL7 (nvme)
Disk /dev/nvme0n1: 1024210MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:   

Number  Start      End        Size      File system  Name                          Flags
        0.02MB     1.05MB     1.03MB    Free Space
 1      1.05MB     274MB      273MB     fat32        EFI system partition          boot
 2      274MB      290MB      16.8MB                 Microsoft reserved partition  msftres
 3      290MB      99364MB    99074MB   ntfs         Basic data partition          msftdata
        99364MB    1022112MB  922748MB  Free Space
 4      1022112MB  1024209MB  2097MB    ntfs         Basic data partition          hidden, diag
        1024209MB  1024210MB  0.34MB    Free Space

Tulosteesta havaitaan, että osioiden 3 ja 4 välissä on noin 922 gigatavua vapaata tilaa. Luo uusi osio vapaaseen tilaan komennolla

mkpart linux ext4 X Y

missä X on "print free" komennon tulosteesta poimittu vapaan tilan alkuosoite (tässä 99364MB) ja Y on tilan loppuosoite (tässä 1022112MB).

Poistu partedistä komennolla

quit

3.4 Katso uudelle osiolle varattu laitenimi komennolla

lsblk

Kun vertaat tulostetta aiempaan, niin huomaat listauksessa uuden osion.

3.5 Alusta salaus komennolla

cryptsetup -y -v luksFormat /dev/nvme0n1p5

missä nvme0n1p5 on lsblk komennon tulosteesta poimittu osion laitenimi. Huomaa, että osion numero (tässä p5) tulee antaa, koska vain yksi levyn osioista salataan!

Avaa salattu osio luettavaksi komennolla

cryptsetup open /dev/nvme0n1p5 root

Alusta ext4-tiedostojärjestelmä salatulle osioille komennolla

mkfs.ext4 /dev/mapper/root

missä root on cryptsetup komennolle annettu osion nimi.

3.6 Liitä tiedostojärjestelmä /mnt hakemistoon komennolla

mount /dev/mapper/root /mnt

Etsi edellä olevista gparted ja lsblk komennon tulosteista EFI-osion laitenimi ja liitä se komennolla

mount --mkdir /dev/nvme0n1p1 /mnt/boot

missä nvme0n1p1 on EFI-osion laitenimi. Tämän jälkeen massamuisti on valmis Linuxin asennusta varten!

4 Linuxin asennus massamuistiin

4.1 Asenna Linuxin ydin ja minimaalinen käyttöjärjestelmä massamuistiin komennolla

pacstrap -K /mnt base linux linux-firmware intel-ucode

4.2 Tallenna tiedostojärjestelmien listaus komennolla

genfstab -U /mnt >> /mnt/etc/fstab

Avaa tiedosto /etc/fstab muokattavaksi komennolla (katso vi-editorin pikaohje sivupalkista)

vi /mnt/etc/fstab

Korvaa tiedostossa ext4-tiedostojärjestelmän kohdalla relatime-määre muotoon noatime. Määre noatime kertoo järjestelmälle, että tiedostojen viimeisintä lukuhetkeä ei tarvitse tallentaa, joka vähentää massamuistiin kirjoittamista.

Lisää tiedoston loppuun rivi:

tmpfs /tmp tmpfs rw,nodev,nosuid,size=8G 0 2

Rivi kertoo järjestelmälle, että hakemisto /tmp pidetään ainoastaan muistissa. Useat ohjelmat kirjoittavat tilapäistiedostoja /tmp hakemistoon, ja rivi edelleen vähentää massamuistiin kirjoittamista.

Valmis tiedosto voi sisältää esimerkiksi 3 riviä:

UUID=11ce0d1c-8954-4070-85d6-fc2faf3c4ef2 / ext4 rw,noatime 0 1
UUID=5AA8-C661 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2
tmpfs /tmp tmpfs rw,nosuid,nodev,size=8G 0 2

4.3 Vaihda juurihakemisto komennolla

arch-chroot /mnt

Tämän jälkeen kaikki käyttöjärjestelmään tekemäsi muutokset koskevat massamuistiin asennettua Linux käyttöjärjestelmää. Huomaa myös, että samalla katkeaa yhteys USB-tikulle tallennettuihin työkaluihin. Jos tarvitset palata takaisin edelliseen vaiheeseen, niin poistu tilasta exit-komennolla.

4.4 Asenna käyttöönotossa tarvitsemasi työkalut komennolla

pacman -S vi dhcpcd font-terminus vim

4.5 Aseta järjestelmän kielet avaamalla tiedosto /etc/locale.gen muokattavaksi komennolla (katso sivupalkista vi-editorin ohje)

vi /etc/locale.gen

Poista kommenttimerkki seuraavien rivien alusta

en_US.UTF-8 UTF-8
fi_FI.UTF-8 UTF-8

Poistu editorista ja luo kielitiedostot valituille kielille komennolla

locale-gen

Valitse järjestelmän oletuskieli äsken asennetuista kielistä komennolla

echo LANG=en_US.UTF-8 > /etc/locale.conf

4.6 Aseta suomalainen näppäimistö ja isompi fontti Linux konsoliin pysyvästi avaamalla tiedosto /etc/vconsole.conf muokattavaksi komennolla

vi /etc/vconsole.conf

Lisää tiedostoon rivit:

KEYMAP=fi
FONT=ter-v32n

4.7 Valitse aikavyöhyke komennolla

ln -s /usr/share/zoneinfo/Europe/Helsinki /etc/localtime

4.8 Aseta koneen kello käymään UTC-aikaa komennolla

hwclock --systohc --utc

4.9 Valitse sisäverkossa näkyvä tietokoneen nimi (tässä arch) ja aseta se komennolla

echo arch > /etc/hostname

4.10 Aseta root-käyttäjän salasana komennolla

passwd

4.11 Aseta tietokone käynnistämään Linux komennolla

bootctl install

Avaa mkinitcpio.conf-tiedosto muokattavaksi komennolla

vi /etc/mkinitcpio.conf

etsi rivi HOOKS ja varmista, että riviltä löytyy keyboard, keymap ja encrypt. Valmis tiedosto sisältää rivin

HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt filesystems fsck)

Rakenna käynnistystiedostot uudelleen komennolla

mkinitcpio -P

Lisää Linux käynnistysvalikkoon komennolla

vi /boot/loader/entries/arch.conf

Syötä tiedoston sisällöksi:

title Arch Linux
sort-key 0000
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options cryptdevice=/dev/nvme0n1p5:root root=/dev/mapper/root rw

missä nvme0n1p5 on Linux-asennuslevyn laitenimi lsblk komennon tulosteesta.

Aseta Arch Linux käynnistymään oletuksena komennolla

vi /boot/loader/loader.conf

Muokkaa tiedoston sisältöä siten, että tiedostossa lukee

default arch.conf
timeout 5
console-mode max

4.12 Ota USB-tikku irti ja käynnistä tietokone uudelleen komennoilla

exit reboot

Jos kaikki meni hyvin, niin Arch Linux käynnistyy massamuistista konsoliin. Kirjaudu sisään root-käyttäjänä edellä antamallasi salasanalla ja ota verkko käyttöön systemctl komennolla kuten aiemmin, niin voit jatkaa Linuxin asennusta haluamaasi suuntaan.

tiistai 25. lokakuuta 2022

Kuinka monella tavalla virheen voi käsitellä

Ethan McCue esittelee blogissaan 11 erilaista tapaa, millä C-kielen funktio voi palauttaa virheen kutsuvalle ohjelmanosalle. McCue ottaa esimerkiksi yksinkertaisen funktion, joka tulkitsee numeron merkkijonossa ja palauttaa vastaavan arvon kokonaislukuna:
int parse_natural_base_10_number(const char* s) {
    int parsed = 0;
    for (size_t i = 0; s[i] != '\0'; i++) {
        parsed *= 10;
        parsed += s[i] - '0';
    }

    return parsed;
}

Ongelma on, miten funktio voi välittää kutsuvalle ohjelmanosalle tiedon, jos parametri s ei ole kelvollinen kokonaisluku.

McCuen esittelemät 11 tapaa ovat karkeasti käännettynä:
1. Unohda koko juttu
Jos virhe tapahtuu vain harvoin, niin ei ole hyödyllistä käyttää työaikaa siihen varautumiseen
2. Luovuta heti
Et voi kuitenkaan korjata virhettä, joten ohjelman on sama kaatua heti
3. Palauta negatiivinen luku
Jos funktio palauttaa normaalisti positiivisia lukuja, niin palauta virhetilanteessa negatiivinen tai muuten normaalin käsittelyalueen ulkopuolella oleva luku, esimerkiksi -1 tai 0x7fffffff
4. Palauta NULL-osoitin
Jos funktio palauttaa normaalisti osoittimen muistialueelle, niin palauta virhetilanteessa NULL-osoitin
5. Palauta boolean-arvo
Tallenna funktion normaali tulos parametrina annettuun osoitteeseen, ja palauta tosi tai epätosi sen mukaan, onnistuiko operaatio vai ei
6. Palauta virhekoodi
Tallenna funktion tulos parametrina annettuun osoitteeseen, ja palauta enum-arvolla tieto onnistumisesta (esim PARSE_NATURAL_SUCCESS) tai virheen tarkempi syy (esim PARSE_NATURAL_BAD_CHARACTER)
7. Palauta boolean-arvo ja virheen sijainti
Tallenna funktion tulos ja virheen sijainti parametreina annettuihin osoitteisiin, jotta funktiota kutsuva koodi voi muodostaa asiallisen virheilmoituksen, kun funktio palauttaa epätosi
8. Palauta virhekoodi ja lisätieto
Jos funktio voi epäonnistua monella eri tavalla, niin palauta virhekoodi enum-arvona ja tallenna virhekoodia koskeva yksityiskohtainen lisätieto erillisessä parametrissa annettuun osoitteeseen
9. Aseta globaali virhelippu
Tallenna virhekoodi ja virheen lisätiedot säikeen sisäiseen tai globaaliin muuttujaan, josta kutsuva koodi voi hakea ne tarvittaessa
10. Palauta tietue
Palauta aina viittaus tietueeseen (struct), joka sisältää virhekoodin, funktion normaalin paluuarvon sekä mahdollisen virheen yksityiskohtaiset lisätiedot
11. Palauta virheolio
Palauta viittaus geneeriseen virheolioon, jota voidaan pyytää muodostamaan varsinainen virheilmoitus tarvittaessa
Kaikki 11 tapaa ovat omalla tavallaan mielenkiintoisia ja suosittelen tutustumaan https://mccue.dev!

Päivitys 19.2.2023: Martin Sústrik vertaa blogissaan C++:n ja C:n virhekäsittelyä. C++ sallii käsitellä virheet myös poikkeuksina, mutta poikkeukset eivät aina ole hyvä juttu!

keskiviikko 27. heinäkuuta 2022

Stylus

Stylus on Chromelle ladattava lisäosa, jolla voi räätälöidä nettisivujen ulkoasua. Jos esimerkiksi Iltalehden värimaailma ei miellytä silmää, niin Stylusilla voit vaihtaa sivuston värimaailman toiseksi!

Itseäni on häirinnyt esimerkiksi Trellon oletusnäkymä kapealla ruudulla:

Oletusnäkymässä usein käyttämäni suosikit-lista jää piiloon Lisää-napin taakse ja työkalurivi jakautuu kahdelle riville vieden turhan paljon tilaa pystysuunnassa. Stylusin avulla saan piilotettua harvemmin tarvittavat toiminnot, jolloin suosikit tulevat suoraan valikkoriville ja työkalut mahtuvat yhdelle riville:

Tämän muutoksen mahdollistaa CSS-tyyli, jonka Stylus asentaa sivulle:

@-moz-document domain("trello.com") {
    /* Piilota työtilan valitsin yläpalkista */
    #trello-root #surface [data-desktop-id="header"] button[data-testid="workspace-switcher"] {
        display: none;
    }
    
    /* Piilota äsken käytetyt yläpalkista */
    #trello-root #surface [data-desktop-id="header"] button[data-testid="recently-viewed-boards-menu"] {
        display: none;
    }
    
    /* Piilota mallit yläpalkista */
    #trello-root #surface [data-desktop-id="header"] button[data-testid="templates-menu"] {
        display: none;
    }
    
    /* Näytä suosikit yläpalkissa myös kapealla ruudulla */
    @media screen and (max-width: 1160px) {
        .uBxJ2o6k5IeFft button:nth-child(3) { 
            display: flex;
        }
    }
    
    /* Piilota lisää-nappi yläpalkista */
    .uB_pTObtvQIxyu {
        display: none;
    }
}

Päivitys 22.7.2023: Päivitetty CSS-tyylit Trellon uusinta versiota varten.

Päivitys 18.2.2023: Tämä sivu kertoi alun perin Stylish-nimisestä laajennuksesta. Kun Stylish alkoi näyttää sivuistoilla mainoksia, niin siirryin käyttämään vastaavaa Stylus-laajennosta.

LibreOfficen MOD-funktio ei toimi!

Käytän LibreOfficen taulukkolaskentaa mm. algoritmien suunnitteluun. Taulukkolaskenta on hyvä työkalu tähän tarkoitukseen, koska algoritmia voi testata erilaisilla syötteillä jo ennen kuin algoritmia tarvitsee toteuttaa millään oikealla ohjelmointikielellä. Erästä algoritmia toteuttaessani huomasin kuitenkin, että LibreOfficen MOD-funktio toimii eri tavalla kuin ohjelmointikielissä yleensä.

MOD-funktiolla lasketaan kahden kokonaisluvun jakojäännös: jos esimerkiksi 9 jaetaan 5:llä, niin 5 mahtuu 9:ään yhden kerran ja jäljelle jää 4. Jos jakajan ja jaettavan etumerkit kuitenkin poikkeavat toisistaan, niin LibreOffice MOD-funktio antaa yllättävän tuloksen. Esimerkiksi -9 jaettuna 12 antaa Libreoffice 7.3.4.2:ssa jakojäännökseksi 3:
Vastaavasti C-kielessä (GCC 12.1.0) sama laskukaava antaa tulokseksi -9:
#include <stdio.h>

int main(void) {
        printf("vastaus=%d\n", -9 % 12);
        return 0;
}
> gcc x.c > ./a.out vastaus=-9

Kyseessä ei ole bugi, vaan jakojäännös voidaan laskea usealla eri algoritmilla ja ohjelmointikielet poikkeavat toisistaan tässä suhteessa: When exactly one of a or n is negative, the naïve definition breaks down, and programming languages differ in how these values are defined. LibreOffice käyttää jakojäännöksen laskemiseen Knuthin algoritmia kun ohjelmointikielet yleensä käyttävät kokonaislukujen jakojäännöksen laskemiseen ns. "truncated division" algoritmia.

LibreOfficessa jakojäännös "truncated division" algoritmilla saadaan kaavalla MOD(ABS(A); ABS(B)) * SIGN(A), missä A on jaettava ja B on jakaja:
Ero on hyvä pitää mielessä, jos käyttää LibreOfficea algoritmien kehittämiseen!