TDCroPower
Elite User
Da mein alter Raspberry 2 so langsam seinen Geist im 24/7 OScam Betrieb aufgibt, habe ich mir einen aktuellen Raspberry 4 besorgt und auch gleich das aktuelle Ubuntu anstatt Raspbian installiert.
Nach einigen erfolgreichen Jahren mit dem Raspberry 2 mit SD Karte, blieb mir die Lebenszeit einer SD Karte immer im Hinterkopf keine Ruhe.
Mythos oder nicht... mir ist in der ganzen Zeit schon eine SD Karte gestorben, obwohl ich die OScam Logs immer unter tmp geschrieben habe und tmp2ram verwendet habe.
Dank Backup meiner Configs, konnte ich das System schnell wieder mit frischer SD Karte aufsetzen... zum Glück war es ein Werktag, wodurch ich schnell an eine neue SD dran kam.
Aktuell mit den kritischen microSD's in der 3er und 4er Serie will ich vorab um eine Lösung eines möglichen Problems Herr werden.
Und genau hier kommt das Thema ReadOnly Betrieb ins Spiel !
Wenn sich einige jetzt gerade fragen...
"Hey, im ReadOnly Betrieb kann ich doch nichts mehr installieren oder bearbeiten?"
--> Antwort: GENAU, aber dafür zeige ich euch hier in der Anleitung wie ihr mit den Kurz-Befehlen "rw" und "ro" zwischen ReadWrite (Lesen+Schreiben) und ReadOnly (Nur Lesen) schnell wechseln könnt!
HINWEIS: ich führe alle Befehle als root User aus, daher sind vor einigen Befehlen davor kein sudo !
Wenn ihr als nicht root User eingeloggt seid, müsst ihr natürlich noch sudo davor setzen!
2.1. zuerst entfernen wir unerwünschte Programme vom System...
Hinweis: hier könnten in Zukunft noch ein paar dazu kommen, aus den anderen Anleitung war lediglich logrotate installiert bei ubuntu.
Falls ich noch weitere finde die man nicht benötigt, füge ich sie hier hinzu!
2.2. nun tauschen wir das Log Managment gegen busybox aus...
2.3. danach räumen wir unser System von liegen gebliebenen Resten auf...
2.4. um swap und den filesystem check zu deaktivieren müssen wir die cmdline.txt editieren...
2.5. fügt am Ende der ersten Zeile "fastboot noswap ro" hinzu...
vorher
nachher
2.6. zusätzlich dazu müssen wir noch random-seed in den schreibbaren Bereich verlagern...
Dazu zuerst das original File entfernen...
2.7. um danach einen Symlink dafür zu erstellen...
2.8. damit beim Neustart im tmp Bereich das File vor dem random-seed service selber zu erstellen müssen wir die service Datei hierzu erweitern...
2.9. fügt im Bereich Service folgende Zeile dazwischen...
sollte dann so aussehen...
2.10. jetzt übergeben wir systemd unsere Änderungen...
2.11. daraufhin stellen wir unsere Filesysteme auf ReadOnly Mode um und verlinken die tmp und System Logs in den tmpfs (Arbeitsspeicher) ...
2.12. hierbei fügt man ro hinter defaults bei beiden ersten mounts hinzu und einige tmpfs mounts...
vorher
nachher
2.13. jetzt sollte euer System beim nächsten Neustart direkt in den ReadOnly Mode booten, das könnt ihr auch direkt testen mit...
2.14. nach dem neustart könnt ihr mit folgendem Befehl prüfen, ob sie im ReadOnly Mode sind...
2.15. hier solltet ihr, in Klammern, bei beiden mounts ein (ro,...) sehen, wenn es so ist... perfekt...
Das funktioniert OnTheFly, also ohne am laufenden Betrieb des Servers irgendwas zu manipulieren bzw. OHNE Neustart !
Theoretisch reicht hier der Befehl für ReadWrite...
und zurück zum ReadOnly...
Da sich diese Befehle keiner merken will, können wir dies in Kurzbefehle packen und somit schnell hin und her wechseln!
3.1. da wir uns nach dem Neustart aktuell im ReadOnly Mode befinden, wechseln wir zunächst in den ReadWrite Mode zurück...
3.2. öffnet nun eure User Bashrc Datei...
3.3. fügt am Ende der Datei folgendes hinzu...
3.4. als nächstes möchten wir sicher stellen, das wir beim Ausloggen nicht vergessen das System wieder in den ReadOnly Mode zu setzen...
3.5. fügt folgendes am Ende hinzu...
3.6. ihr müsst euch jetzt ausloggen und neu per ssh anmelden, im Prompt links solltet ihr jetzt sofort sehen in welchem Modus (ro) oder (rw) ihr seid und könnt mit dem Kurzbefehl ro bzw. rw leicht hin und her wechseln...
Da im ReadOnly Mode das Oscam WebInterface so natürlich nicht komfortabel funktionieren kann, brauche wir einen abgegrenzten Bereich indem unsere eigenen Programme doch ab und an im ReadWrite Modus schreiben können, unabhängig was auf dem System gerade los ist.
Leider kann man im laufenden Betrieb die große root Partition /dev/mmcblk0p2 nicht verkleinern um davon eine weitere Partition zu erstellen die wir hierfür benötigen.
Ladet euch dafür am einfachsten die
4.1. habt ihr die GParted Live CD erfolgreich im VM Tool gestartet, wählt ihr im ersten Auswahl Fenster GParted Live (Default settings) aus...
4.2. danach einfach Don't touch keymap...
4.3. als Sprache in unserem Beispiel am besten 10 für Deutsch...
4.4. als Mode könnt ihr einfach mit 0 den GParted automatically nutzen...
4.5. wählt nun oben rechts eure microSD aus (die könnt ihr in diesem Schritt an euren PC anschließen)...
4.6. mit rechtsklick auf die 2te Partition mit der höheren Größe und dann Größe ändern/verschieben...
4.7. hier setzt ihr unter Neue Größe (MB) fest, wie groß die root Partition in Zukunft groß sein soll, in meinem Beispiel bei einer 32GB microSD wird 10GB an root gehen und 22GB an die neue Schreibpartition...
4.8. wählt nun mit Rechtsklick auf die nicht zugeteilt "Partition" und dann Neu aus...
4.9. hier müsst ihr lediglich eurer neuen Partition eine Bezeichnung geben, in meinem Beispiel Datenkrake...
4.10. klickt nun auf den grünen Pfeil in der Menüleiste um alle offenen Operationen auszuführen...
4.11. eure in den letzten Schritten definierten Operationen werden nach einander automatisch ausgeführt...
4.12. am Ende solltet ihr einen ähnlichen Details Bericht haben wie hier...
4.13. zurück am Raspberry führt folgenden Befehl aus um alle verfügbaren Partitionen zu sehen...
wenn eure neue Partition hier aufgelistet wird, in meinem Beispiel die datenkrake, waren die oberen Schritte soweit korrekt...
4.14. jetzt erstellt euch ein Verzeichnis in das diese Partition gemounted werden soll, in meinem Beispiel unter /mnt...
kontrolle...
4.15. nun öffnen wir wie in 2.16. die fstab um den Mount zu konfigurieren...
4.16. fügt die Zeile 3 so ein wie es hier zu sehen ist, bei LABEL=BESCHREIBUNG muss eure gesetzte Beschreibung hinein bzw. die aus Schritt 4.13. ohne Hochkomma zu sehende und natürlich euren Pfad zum in Schritt 4.14. erstellten Verzeichnis...
4.17. mit folgendem Befehl führen wir die fstab im laufenden Betrieb aus...
4.18. eure Partition sollte nun gemounted sein und ihr könnt im ReadOnly Modus in diese hinein schreiben...
4.18. erstellt nun ein Verzeichnis ipc in eurer Partition...
4.19. verschiebt aus /var/etc alle Dateien nach /mnt/datenkrake/ipc und verlinkt es mit dem Verzeichnis /var/etc...
4.20. sicherheitshalber stoppt vor dem nächsten Schritt OScam damit bei den nächsten Befehlen alles sauber durchlaufen kann...
4.21. nun wollen wir noch die im laufenden Betrieb von Oscam erstellten Cache Logs (die man leider nicht per oscam.conf konfigurieren kann) nicht hier haben, sondern im /tmp Verzeichnis (Arbeitsspeicher)...
Hinweis: die anderen Log Dateien habe ich in der oscam.conf unter Global >>> logfile, emmlogdir und lb_savepath schon auf /tmp verschoben, daher brauch ich dafür kein Symlink.
Das wars auch schon und Oscam sollte wieder sauber laufen.
Quelle:
Nach einigen erfolgreichen Jahren mit dem Raspberry 2 mit SD Karte, blieb mir die Lebenszeit einer SD Karte immer im Hinterkopf keine Ruhe.
Mythos oder nicht... mir ist in der ganzen Zeit schon eine SD Karte gestorben, obwohl ich die OScam Logs immer unter tmp geschrieben habe und tmp2ram verwendet habe.
Dank Backup meiner Configs, konnte ich das System schnell wieder mit frischer SD Karte aufsetzen... zum Glück war es ein Werktag, wodurch ich schnell an eine neue SD dran kam.
Aktuell mit den kritischen microSD's in der 3er und 4er Serie will ich vorab um eine Lösung eines möglichen Problems Herr werden.
Und genau hier kommt das Thema ReadOnly Betrieb ins Spiel !
Wenn sich einige jetzt gerade fragen...
"Hey, im ReadOnly Betrieb kann ich doch nichts mehr installieren oder bearbeiten?"
--> Antwort: GENAU, aber dafür zeige ich euch hier in der Anleitung wie ihr mit den Kurz-Befehlen "rw" und "ro" zwischen ReadWrite (Lesen+Schreiben) und ReadOnly (Nur Lesen) schnell wechseln könnt!
1. Voraussetzung
Für meine Schritte zur Umsetzung benötigt ihr zunächst eine fertige Installation von Ubuntu auf eurem Raspberry, eine schon vorhandene Anleitung findet ihr drüben von @Osprey ...Ubuntu 20.04 LTS
Seit Heute gibt es das neue Ubuntu 20.04 LTS :hearteyes: und ab Morgen wird das auf meinem Raspberry Pi 3+ installiert Download hier: Du musst angemeldet sein, um das Element zu sehen. Mit 7Zip entpacken und mit dem Win32DiskImager auf die SD schreiben. In den Raspberry stecken und starten.
www.digital-eliteboard.com
2. Auf gehts
Habt ihr Ubuntu mit der Anleitung von @Osprey erfolgreich installiert können wir endlich starten.HINWEIS: ich führe alle Befehle als root User aus, daher sind vor einigen Befehlen davor kein sudo !
Wenn ihr als nicht root User eingeloggt seid, müsst ihr natürlich noch sudo davor setzen!
2.1. zuerst entfernen wir unerwünschte Programme vom System...
Hinweis: hier könnten in Zukunft noch ein paar dazu kommen, aus den anderen Anleitung war lediglich logrotate installiert bei ubuntu.
Falls ich noch weitere finde die man nicht benötigt, füge ich sie hier hinzu!
Code:
apt-get remove --purge logrotate
2.2. nun tauschen wir das Log Managment gegen busybox aus...
Code:
apt-get install busybox-syslogd; dpkg --purge rsyslog
2.3. danach räumen wir unser System von liegen gebliebenen Resten auf...
Code:
apt autoremove --purge
2.4. um swap und den filesystem check zu deaktivieren müssen wir die cmdline.txt editieren...
Code:
nano /boot/firmware/cmdline.txt
2.5. fügt am Ende der ersten Zeile "fastboot noswap ro" hinzu...
vorher
Code:
net.ifnames=0 dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc
Code:
net.ifnames=0 dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc fastboot noswap ro
2.6. zusätzlich dazu müssen wir noch random-seed in den schreibbaren Bereich verlagern...
Dazu zuerst das original File entfernen...
Code:
rm /var/lib/systemd/random-seed
2.7. um danach einen Symlink dafür zu erstellen...
Code:
ln -s /tmp/random-seed /var/lib/systemd/random-seed
2.8. damit beim Neustart im tmp Bereich das File vor dem random-seed service selber zu erstellen müssen wir die service Datei hierzu erweitern...
Code:
nano /lib/systemd/system/systemd-random-seed.service
2.9. fügt im Bereich Service folgende Zeile dazwischen...
Code:
ExecStartPre=/bin/echo “” >/tmp/random-seed
Code:
...
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/bin/echo “” >/tmp/random-seed
ExecStart=/lib/systemd/systemd-random-seed load
ExecStop=/lib/systemd/systemd-random-seed save
...
2.10. jetzt übergeben wir systemd unsere Änderungen...
Code:
systemctl daemon-reload
2.11. daraufhin stellen wir unsere Filesysteme auf ReadOnly Mode um und verlinken die tmp und System Logs in den tmpfs (Arbeitsspeicher) ...
Code:
nano /etc/fstab
2.12. hierbei fügt man ro hinter defaults bei beiden ersten mounts hinzu und einige tmpfs mounts...
vorher
Code:
LABEL=writable / ext4 defaults 0 0
LABEL=system-boot /boot/firmware vfat defaults 0 1
Code:
LABEL=writable / ext4 defaults,ro 0 0
LABEL=system-boot /boot/firmware vfat defaults,ro 0 1
tmpfs /var/log tmpfs nodev,nosuid 0 0
tmpfs /var/tmp tmpfs nodev,nosuid 0 0
tmpfs /tmp tmpfs rw,mode=1777 0 0
tmpfs /var/lib/dhcp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755 0 0
tmpfs /var/lib/dhcpcd5 tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755 0 0
tmpfs /var/lock tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755 0 0
tmpfs /var/run tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755 0 0
tmpfs /var/spool tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755 0 0
2.13. jetzt sollte euer System beim nächsten Neustart direkt in den ReadOnly Mode booten, das könnt ihr auch direkt testen mit...
Code:
reboot
2.14. nach dem neustart könnt ihr mit folgendem Befehl prüfen, ob sie im ReadOnly Mode sind...
Code:
mount | grep /dev/mmc
2.15. hier solltet ihr, in Klammern, bei beiden mounts ein (ro,...) sehen, wenn es so ist... perfekt...
Code:
root@ubuntu(ro):~# mount | grep /dev/mmc
/dev/mmcblk0p2 on / type ext4 (ro,relatime)
/dev/mmcblk0p1 on /boot/firmware type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
3. Wechseln zwischen ReadWrite <-> ReadOnly
Wie am Anfang schon versprochen, wollen wir für zukünftige Installationen oder Änderungen von Dateien schnell in den Schreibmodus wechseln und am Ende sicher wieder zurück in den ReadOnly Mode!Das funktioniert OnTheFly, also ohne am laufenden Betrieb des Servers irgendwas zu manipulieren bzw. OHNE Neustart !
Theoretisch reicht hier der Befehl für ReadWrite...
Code:
mount -o remount,rw /
Code:
mount -o remount,ro /
3.1. da wir uns nach dem Neustart aktuell im ReadOnly Mode befinden, wechseln wir zunächst in den ReadWrite Mode zurück...
Code:
mount -o remount,rw /
3.2. öffnet nun eure User Bashrc Datei...
Code:
nano /etc/bash.bashrc
3.3. fügt am Ende der Datei folgendes hinzu...
Code:
# set variable identifying the filesystem you work in (used in the prompt below)
set_bash_prompt(){
fs_mode=$(mount | sed -n -e "s/^\/dev\/.* on \/ .*(\(r[w|o]\).*/\1/p")
PS1='\[\033[1;33m\]\u\[\033[00m\]\[\033[1;37m\]@\[\033[00m\]\[\033[01;32m\]\h\[\033[00m\]\[\033[0;31m\]${fs_mode:+($fs_mode)}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] \$ '
}
alias ro='mount -o remount,ro / ; mount -o remount,ro /boot/firmware'
alias rw='mount -o remount,rw / ; mount -o remount,rw /boot/firmware'
# setup fancy prompt"
PROMPT_COMMAND=set_bash_prompt
3.4. als nächstes möchten wir sicher stellen, das wir beim Ausloggen nicht vergessen das System wieder in den ReadOnly Mode zu setzen...
Code:
nano /etc/bash.bash_logout
3.5. fügt folgendes am Ende hinzu...
Code:
mount -o remount,rw /
history -a
mount -o remount,ro /
mount -o remount,ro /boot/firmware
3.6. ihr müsst euch jetzt ausloggen und neu per ssh anmelden, im Prompt links solltet ihr jetzt sofort sehen in welchem Modus (ro) oder (rw) ihr seid und könnt mit dem Kurzbefehl ro bzw. rw leicht hin und her wechseln...
Code:
root@ubuntu(ro):~# touch bla
touch: cannot touch 'bla': Read-only file system
root@ubuntu(ro):~# rw
root@ubuntu(rw):~# touch bla
root@ubuntu(rw):~# rm bla
root@ubuntu(rw):~# ro
root@ubuntu(ro):~#
4. Schreibpartition erstellen für Oscam configs oder ähnlichem
Da im ReadOnly Mode das Oscam WebInterface so natürlich nicht komfortabel funktionieren kann, brauche wir einen abgegrenzten Bereich indem unsere eigenen Programme doch ab und an im ReadWrite Modus schreiben können, unabhängig was auf dem System gerade los ist.
Leider kann man im laufenden Betrieb die große root Partition /dev/mmcblk0p2 nicht verkleinern um davon eine weitere Partition zu erstellen die wir hierfür benötigen.
Ladet euch dafür am einfachsten die
Sie müssen registriert sein, um Links zu sehen.
herunter und startet sie mit einem kostenlosen VM Tool wie
Sie müssen registriert sein, um Links zu sehen.
oder
Sie müssen registriert sein, um Links zu sehen.
.4.1. habt ihr die GParted Live CD erfolgreich im VM Tool gestartet, wählt ihr im ersten Auswahl Fenster GParted Live (Default settings) aus...
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
Du musst angemeldet sein, um Bilder zu sehen.
4.13. zurück am Raspberry führt folgenden Befehl aus um alle verfügbaren Partitionen zu sehen...
Code:
blkid
Code:
root@ubuntu(rw):~# blkid
/dev/mmcblk0p1: LABEL_FATBOOT="system-boot" LABEL="system-boot" UUID="B7xxxxxxE2" TYPE="vfat" PARTUUID="abxxxxxx-01"
/dev/mmcblk0p2: LABEL="writable" UUID="483efxxxxxxxxxxxx56f7" TYPE="ext4" PARTUUID="abxxxxx-02"
/dev/mmcblk0p3: LABEL="datenkrake" UUID="0591fxxxxxxxxxxxxxx07f4" TYPE="ext4" PARTUUID="abxxxxxx-03"
/dev/loop0: TYPE="squashfs"
/dev/loop1: TYPE="squashfs"
/dev/loop2: TYPE="squashfs"
/dev/loop3: TYPE="squashfs"
/dev/loop4: TYPE="squashfs"
/dev/loop5: TYPE="squashfs"
4.14. jetzt erstellt euch ein Verzeichnis in das diese Partition gemounted werden soll, in meinem Beispiel unter /mnt...
Code:
mkdir /mnt/datenkrake
Code:
root@ubuntu(rw):~# ls -l /mnt/
total 4
drwxr-xr-x 4 root root 4096 Feb 15 15:46 datenkrake
root@ubuntu(rw):~#
4.15. nun öffnen wir wie in 2.16. die fstab um den Mount zu konfigurieren...
Code:
nano /etc/fstab
4.16. fügt die Zeile 3 so ein wie es hier zu sehen ist, bei LABEL=BESCHREIBUNG muss eure gesetzte Beschreibung hinein bzw. die aus Schritt 4.13. ohne Hochkomma zu sehende und natürlich euren Pfad zum in Schritt 4.14. erstellten Verzeichnis...
Code:
LABEL=writable / ext4 defaults,ro 0 0
LABEL=system-boot /boot/firmware vfat defaults,ro 0 1
LABEL=datenkrake /mnt/datenkrake ext4 defaults 0 0
tmpfs /var/log tmpfs nodev,nosuid 0 0
tmpfs /var/tmp tmpfs nodev,nosuid 0 0
tmpfs /tmp tmpfs nodev,nosuid 0 0
4.17. mit folgendem Befehl führen wir die fstab im laufenden Betrieb aus...
Code:
mount -a
4.18. eure Partition sollte nun gemounted sein und ihr könnt im ReadOnly Modus in diese hinein schreiben...
Code:
root@ubuntu(rw):~# mount | grep mmc
/dev/mmcblk0p2 on / type ext4 (rw,relatime)
/dev/mmcblk0p3 on /mnt/datenkrake type ext4 (rw,relatime)
/dev/mmcblk0p1 on /boot/firmware type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
root@ubuntu(rw):~# ro
root@ubuntu(ro):~# mount | grep mmc
/dev/mmcblk0p2 on / type ext4 (ro,relatime)
/dev/mmcblk0p3 on /mnt/datenkrake type ext4 (rw,relatime)
/dev/mmcblk0p1 on /boot/firmware type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
root@ubuntu(ro):~# touch /mnt/datenkrake/bla
root@ubuntu(ro):~# ll /mnt/datenkrake/bla
-rw-r--r-- 1 root root 0 Feb 15 20:51 /mnt/datenkrake/bla
root@ubuntu(ro):~# ll /mnt/datenkrake
total 20
-rw-r--r-- 1 root root 0 Feb 15 20:51 bla
drwx------ 2 root root 16384 Feb 15 15:14 lost+found
root@ubuntu(ro):~#
4.18. erstellt nun ein Verzeichnis ipc in eurer Partition...
Code:
mkdir /mnt/datenkrake/ipc
4.19. verschiebt aus /var/etc alle Dateien nach /mnt/datenkrake/ipc und verlinkt es mit dem Verzeichnis /var/etc...
Code:
mv /var/etc/* /mnt/datenkrake/ipc/; ln -s /mnt/datenkrake/ipc /var/etc
4.20. sicherheitshalber stoppt vor dem nächsten Schritt OScam damit bei den nächsten Befehlen alles sauber durchlaufen kann...
Code:
o stop
4.21. nun wollen wir noch die im laufenden Betrieb von Oscam erstellten Cache Logs (die man leider nicht per oscam.conf konfigurieren kann) nicht hier haben, sondern im /tmp Verzeichnis (Arbeitsspeicher)...
Code:
touch /tmp/oscam.ccache; ln -s /tmp/oscam.ccache /mnt/datenkrake/ipc/oscam.ccache
touch /tmp/oscam.emmcache; ln -s /tmp/oscam.emmcache /mnt/datenkrake/ipc/oscam.emmcache
touch /tmp/oscam.emmstat; ln -s /tmp/oscam.emmstat /mnt/datenkrake/ipc/oscam.emmstat
Hinweis: die anderen Log Dateien habe ich in der oscam.conf unter Global >>> logfile, emmlogdir und lb_savepath schon auf /tmp verschoben, daher brauch ich dafür kein Symlink.
Das wars auch schon und Oscam sollte wieder sauber laufen.
Quelle:
Sie müssen registriert sein, um Links zu sehen.
Zuletzt bearbeitet: