Openhabian prevent extension of partition

Hi,

I want to use an nfs share on my NAS as root filesystem to be used on a raspberry pi in order to avoid sd card corruption issues. For this I’ve unpacked the openhabian 1.4 image and copied it to the nfs share. I only need an sd card of the raspi for booting an handing over to the nfs share (by modifiying commandline.txt).
As written in the openhabian 1.4 documentation the system performs an initial installation / configuration procedure including an automatic extension of the root partition to the entire sd card.
Now what would happen if I boot for the first time and perform the installation? What would happen to the nfs share (and the entire NAS) if openhabian starts the repartition procedure? Is there a way to suppress this behaviour?
Regards,

Udo Eisenbarth

Sounds like a smart idea but wouldn’t that be kinda slow?

  1. If using a Raspberry Pi 3 (or B,+) afaik you don’t need any SD Card but only a TFTP server + NFS share + DHCP configuration in question of BOOTP(?) to boot your Raspberry from Net.
  2. I’m pretty sure that there is no chance to expand a nfs share from client side :wink:
  3. @illnesse Not necessarily, as at least the Raspberry 3B+ has GBit network, attached via USB2, so all in all 300MBit/s in real, and guess what, even the SD Card is connected through USB2…

You should run the image from the sd card until installation procedure is finished. Afterwards you should use the sd card as source for your nfs share.

In this scenario it might make more sense to use the manual openHABian installation instructions. That way you can start with a vanilla Raspbian that will exactly match any of the tutorials you find online. Then once everything is set up on your NAS follow the manual openHABian installation steps to configure everything.

1 Like

Interesting idea. I wonder kernel and initrd can also be downloaded from NAS during netboot. I don’t know if netboot is supported by rasppi board. That would make rasppi totally cardless.

RPi 3 and 3B support cardless network booting, but only after booting with a raspbian card with a special setting in boot.

https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/net_tutorial.md

Older RPis need an SD card to start the boot process.

Interesting. Now the next thing would be how we can minimize OH response times due a nw fs. I think /tmp is memory based or could be made so if there are no large tmp files created by applications. Logging, I am not sure RandomAccessFile Appender will do well on nw fs, need to try out. Older appenders should work fine.
Any other things that you guys can think of that would affect OH response times? Given that nw is LAN 100 mbps at least.

It’s pretty common to carve off some tmpfs space for /var/log, /var/tmp, and /tmp as tmpfs volumes. You give up some RAM to do this and of course those files disappear on reboot or loss of power. I do this routinely on my RPi devices that don’t do a whole lot or are remotely deployed so replacing the SD card is a relative hardship (e.g. the openHAB I have deployed at my dad’s house an hour’s drive away).

Here is my /etc/fstab of my remote OH RPi for the curious. I did a manual openHABian install on it and it is connected to my home network over an OpenVPN connection.

proc            /proc           proc    defaults          0       0
PARTUUID=7ba75bb5-01  /boot           vfat    defaults          0       2
PARTUUID=7ba75bb5-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
tmpfs /tmp tmpfs defaults,noatime,nosuid,size=100m 0 0
tmpfs /var/tmp tmpfs defaults,noatime,nosuid,size=30m 0 0
tmpfs /var/log tmpfs defaults,noatime,nosuid,mode=0755,size=100m 0 0

/usr/share/openhab2          /srv/openhab2-sys           none bind 0 0
/etc/openhab2                /srv/openhab2-conf          none bind 0 0
/var/lib/openhab2            /srv/openhab2-userdata      none bind 0 0
/var/log/openhab2            /srv/openhab2-logs          none bind 0 0
/usr/share/openhab2/addons   /srv/openhab2-addons        none bind 0 0

//fafnir.koshak.net/backups/ /mnt/backups cifs credentials=/etc/samba/.smbcredentials,uid=1000,gid=1000 0 0

Note that openHABian created the openhab2 folders. fafnir is my openMediaVault NAS and I have Amanda set up to backup this RPi there. The three tmpfs lines are creating and mounting RAM disks over the three folders where the most writes take place.

You can even go so far as to make / read only, though it’s a pain because there are some files that need to be written to periodically like /etc/fake-hwclock and such. I don’t run this way any longer but have done so in the past. It was a fun experiment but in the end is didn’t really add anything and made using the machine a major PITA.

For the curious, here is the Ansible playbook I wrote to setup my RPi readonly. It probably doesn’t work, it has been over a year since I last ran it and even then I only half ran it (i.e. did a bunch of steps manually).

---
#- name: Add aliases and fancy prompt to show status of FS
#  blockinfile:
#    state: present
#    dest: /etc/bash.bashrc
#    block: |
#      # 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[01;32m\]\u@\h${fs_mode:+($fs_mode)}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
#      }
#
#      alias ro='sudo mount -o remount,ro / ; sudo mount -o remount,ro /boot'
#      alias rw='sudo mount -o remount,rw / ; sudo mount -o remount,rw /boot'
#
#      # setup fancy prompt"
#      PROMPT_COMMAND=set_bash_prompt
#  become: yes
#  when: "'readonly' in group_names"
#
#- name: Set permissions on /tmp
#  file:
#    mode: a+rwx
#    path: /tmp
#    state: directory
#  become: yes
#  when: "'readonly' in group_names"
#
#- name: Mount tempfs directories
#  mount:
#    path: "{{ item }}"
#    src: tmpfs
#    fstype: tmpfs
#    opts: nosuid,nodev
#    state: mounted
#  become: true
#  when: "'readonly' in group_names"
#  with_items:
#    - /tmp
#    - /var/log
#    - /var/tmp
#
#- name: Backup dhcp
#  command: cp -r /var/lib/dhcp /tmp
#  become: yes
#  when: "'readonly' in group_names"
#
##- name: Remove contents of folders pending relinking to /tmp
##  shell: /bin/rm -rf {{ item }}
##  become: yes
##  when: "'readonly' in group_names"
##  with_items:
###    - /var/lock/*
##    - /var/spool/*
###    - /var/run/*
##    - /var/lib/dhcp/*
#
#- name: Create softlinks to /tmp
#  file:
#    src: "{{ item }}"
#    dest: /tmp
#    state: link
#  become: yes
#  when: "'readonly' in group_names"
#  with_items:
#    - /var/lock
#    - /var/spool
#    - /var/run
#    - /var/lib/dhcp
#
#- name: Reboot
#  include_role:
#    name: reboot
#  when: "'readonly' in group_names"

# Did all of the above manually
- name: Add cron job to reset permissions on /tmp on boot
  cron:
    name: "add write to /tmp"
    special_time: reboot
    job: "chmod a+w /tmp > /dev/null"

- name: Configure boot command line
  replace:
    dest: /boot/cmdline.txt
    regexp: 'otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait'
    replace: 'otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fastboot noswap ro'
  become: yes
  when: "'readonly' in group_names"


- name: Move dhcpd lock file to temp
  replace:
    dest: /etc/systemd/system/dhcpcd5
    regexp: '\=/run/dhcpcd.pid'
    replace: '\=/var/run/dhcpcd.pid'
  become: yes
  when: "'readonly' in group_names"

- name: update fake-hwclock cron job to remount / rw and then mount it back
  copy:
    dest: /etc/cron.hourly/fake-hwclock
    src: fake-hwclock
  become: yes
  when: "'readonly' in group_names"

- name: Check for presence of Tripwire cron job
  stat: path=/etc/cron.daily/tripwire
  register: tripwire_cron
  when: "'readonly' in group_names"

- name: Update cron job to remount rw before running check
  copy:
    dest: /etc/cron.daily/tripwire
    src: tripwire-cron
  become: yes
  when: ("'readonly' in group_names") and
        (tripwire_cron.stat.exists == True)

- name: Update apt daily script to remount rw before running
  copy:
    dest: /etc/cron.daily/apt
    src: apt
  become: yes
  when: "'readonly' in group_names"

- name: Update dpkg daily script to remount rw before running
  copy:
    dest: /etc/cron.daily/dpkg
    src: dpkg
  become: yes
  when: "'readonly' in group_names"

- name: Update logrotate daily script to remount rw before running
  copy:
    dest: /etc/cron.daily/logrotate
    src: logrotate
  become: yes
  when: "'readonly' in group_names"

- name: Update man-db daily script to remount rw before running
  copy:
    dest: /etc/cron.daily/man-db
    src: man-db
  become: yes
  when: "'readonly' in group_names"

- name: Update man-db weekly script to remount rw before running
  copy:
    dest: /etc/cron.weekly/man-db
    src: man-db
  become: yes
  when: "'readonly' in group_names"

- name: Update passwd daily script to remount rw before running
  copy:
    dest: /etc/cron.daily/passwd
    src: passwd
  become: yes
  when: "'readonly' in group_names"

- name: Remove some start scripts
  shell: /sbin/insserv -r bootlogs; /sbin/insserv -r console-setup
  become: yes
  when: "'readonly' in group_names"

- name: Set boot FS as readonly
  replace:
    dest: /etc/fstab
    regexp: '/dev/mmcblk0p1  /boot           vfat    defaults          0       2'
    replace: '/dev/mmcblk0p1  /boot           vfat    defaults,ro          0       2'
  become: yes
  when: "'readonly' in group_names"

- name: Set root as readonly
  replace:
    dest: /etc/fstab
    regexp: '/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1'
    replace: '/dev/mmcblk0p2  /               ext4    defaults,noatime,ro  0       1'
  become: yes
  when: "'readonly' in group_names"

- name: Reboot
  include_role:
    name: reboot
  when: "'readonly' in group_names"

Note that most of the copies at the end of the playbook are all the cron jobs that write to the file system that needed to be altered to remount the file system read/write so they could do their job.

I’m not sure why it would be significantly different in terms of performance. The overwhelming set of operations are still appends and as long as the file is kept open for writing (as it should be) the logger doesn’t have to seek around the file for the insertion point, it’s already there after the first write. Unless this appender works differently than I’m assuming.

Boot time/OH startup is where the most file reads are taking place so that could suffer some performance issues. I’ve seen some reports of 10 minutes to an hour for OH start times for some users on RPis (I was and still am shocked at that). This might exacerbate that problem. NOTE: we have discovered this is caused in part by explicitly using lots of primitives in Rules.

Except for logging and persistence OH doesn’t have too many writes in comparison so I wouldn’t expect too much of an impact. And since persistence is occurring in background threads I wouldn’t expect it to impact the overall performance of OH all that much. In very rare cases you may need to add short Thread::sleeps before you can make calls to the historicState methods on the Item and be guaranteed to get results that include the event that triggered the Rule. This should be a very rare occurrence if it is ever needed.

As for the logging, I don’t know if the log statements block on write or if the appenders cache the logging and write it out to disk in the background. If it is caching then it seems pretty unlikely that the responsiveness of OH would be that impacted at all. The primary impact would be on a crash not necessarily having the latest logs. It’s probably configurable.

It would be interesting to see some numbers showing what the impact of running OH off of a NAS really would be. Enough users set up their RPis this way to run OH that I don’t think the performance impact is enough to offset the potential benefits.

1 Like

The random access appender mainly tries to re-arrange entries according to timestamp. For that it has to keep a larger scope and a different flush cycle. I think thats gonna cause a penalty on nw fs. It was causing lot of issues for me on simple local sd based ext4 fs. I don’t use that appender. Your mileage may vary. :slight_smile: