Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle new update mechanism disable #353

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

Conversation

Eeems
Copy link
Contributor

@Eeems Eeems commented Jun 5, 2024

No description provided.

@Eeems
Copy link
Contributor Author

Eeems commented Jun 5, 2024

All swupdate related files I was able to find in a rM1 update image:

/etc/systemd/system/multi-user.target.wants/swupdate.service
/etc/systemd/system/sockets.target.wants/swupdate.socket
/etc/swupdate.cfg
/lib/systemd/system-preset/98-swupdate.preset
/lib/systemd/system/swupdate.service.d
/lib/systemd/system/swupdate.service.d/swupdate-service-override.conf
/lib/systemd/system/swupdate.service
/lib/systemd/system/swupdate.socket.d
/lib/systemd/system/swupdate.socket.d/swupdate-socket-override.conf
/lib/systemd/system/swupdate-progress.service
/lib/systemd/system/swupdate.socket
/usr/bin/swupdate-progress
/usr/bin/swupdate
/usr/bin/swupdate-ipc
/usr/lib/swupdate
/usr/lib/swupdate/conf.d/09-swupdate-args
/usr/lib/swupdate/swupdate.sh
/usr/lib/libswupdate.so.0.1
/usr/lib/tmpfiles.d/swupdate.conf
/usr/sbin/swupdate-from-image-file
/usr/share/common-licenses/swupdate-tools-hawkbit
/usr/share/common-licenses/swupdate-tools-ipc
/usr/share/common-licenses/swupdate-rootdev
/usr/share/common-licenses/swupdate-progress
/usr/share/common-licenses/swupdate
/usr/share/common-licenses/swupdate-helper
/usr/share/swupdate
/usr/share/swupdate/swupdate-payload-key-pub.pem

Some files of interest:

  • /usr/lib/swupdate/conf.d/09-swupdate-args
    rootfs=$(swupdate -g)
    
    if [ "$rootfs" == '/dev/mmcblk1p2' ]; then
        selection="-e stable,copy2"
    else
        selection="-e stable,copy1"
    fi
    
    # Parameters for Suricatta
    # If this variable is empty (e.g. ..=""), Suricatta mode wont run
    # -d disables the polling of the backend. Swupdate now waits for ipc commands
    # -x disables TLS cert verification
    # See swupdate.sh for the logic
    SWUPDATE_SURICATTA_ARGS=" -d -x "
    
    
    CFGFILE="/tmp/swupdate.cfg"
    
    # We now have the swupdate startup parameters we need
    # Disable bootloader transaction and update state markers
    SWUPDATE_ARGS=" -m -M"
    # Public Key
    SWUPDATE_ARGS+=" -k /usr/share/swupdate/swupdate-payload-key-pub.pem"
    # Set hardware-compatibility, update partition and cfg path
    SWUPDATE_ARGS+=" -H reMarkable1:1.0 ${selection} -f ${CFGFILE}"
    
    I would be interested to know what is in /tmp/swupdate.cfg when it exists.
  • /lib/systemd/system/swupdate.service.d/swupdate-service-override.conf
    [Unit]
    PartOf=memfaultd.service
    
  • /lib/systemd/system/swupdate.socket.d/swupdate-socket-override.conf
    [Unit]
    PartOf=swupdate.service
    
  • /lib/systemd/system/swupdate.service
    [Unit]
    Description=SWUpdate daemon
    Documentation=https://github.com/sbabic/swupdate
    Documentation=https://sbabic.github.io/swupdate
    
    [Service]
    Type=notify
    ExecStart=/usr/lib/swupdate/swupdate.sh
    KillMode=mixed
    
    [Install]
    WantedBy=multi-user.target
    
  • /lib/systemd/system/swupdate.socket
    [Unit]
    Description=SWUpdate socket listener
    Documentation=https://github.com/sbabic/swupdate
    Documentation=https://sbabic.github.io/swupdate
    
    [Socket]
    ListenStream=/tmp/sockinstctrl
    ListenStream=/tmp/swupdateprog
    
    [Install]
    WantedBy=sockets.target
    

@Eeems
Copy link
Contributor Author

Eeems commented Jun 6, 2024

More files of interest:

  • /usr/bin/fakeupdateengine_service
  • /lib/systemd/system/update-engine.service.d/override.conf
    [Unit]
    PartOf=swupdate.service
    
  • /etc/systemd/system/multi-user.target.wants/update-engine.service symlink to /etc/systemd/system/update-engine.service
  • /etc/systemd/system/update-engine.service
    [Unit]
    Description=Fake Update Engine
    After=dbus.service swupdate.service
    Requires=dbus.service swupdate.service
    
    [Service]
    Type=dbus
    BusName=no.remarkable.update1
    ExecStart=/usr/bin/fakeupdateengine_service
    User=root
    Restart=on-failure
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target
    

@Eeems
Copy link
Contributor Author

Eeems commented Jun 6, 2024

I've been trying to track down what handles getting the update to the device, and from there what the server it's pulling it from is. I believe this is used somehow: https://docs.memfault.com/docs/linux/reference-memfaultd-configuration/

@Eeems
Copy link
Contributor Author

Eeems commented Jun 6, 2024

/etc/memfaultd.conf

{
  "persist_dir": "/home/root/.memfault/",
  "upload_interval_seconds": 1200,
  "heartbeat_interval_seconds": 1200,
  "enable_data_collection": true,
  "software_version": "3.11.2.5",
  "software_type": "device",
  "project_key": "JLPsMk3iNn9rmBptmhVq2NYtO4RaiFM7",
  "base_url": "https://device.cloud.remarkable.com",
  "swupdate": {
    "input_file": "/etc/swupdate.cfg",
    "output_file": "/tmp/swupdate.cfg"
},
  "http_server": {
    "bind_address": "127.0.0.1:8787"
},
  "coredump": {
    "coredump_max_size_kib": 96000,
    "rate_limit_count": 5,
    "rate_limit_duration_seconds": 3600,
    "storage_min_headroom_kib": 10240,
    "storage_max_usage_kib": 96000
  }
}

@Eeems
Copy link
Contributor Author

Eeems commented Jun 6, 2024

  • /lib/systemd/system/memfaultd.service
    [Unit]
    Description=memfaultd daemon
    After=\
    local-fs.target \
    network.target \
    dbus.service \
    
    Before=\
    swupdate.service \
    collectd.service \
    
    [Service]
    Type=forking
    PIDFile=/run/memfaultd.pid
    ExecStart=/usr/bin/memfaultd --daemonize
    # Wait for the PID file to be populated before returning
    ExecStartPost=/bin/sh -c "while [ $(cat /run/memfaultd.pid 2>/dev/null | wc -c) -eq 0 ]; do sleep 0.1; done"
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    
  • /lib/systemd/system/memfaultd.service.d/override.conf
    [Unit]
    After=home.mount
    
    [Service]
    # Default if no override key is found
    Environment=CONF_FILE=/etc/memfaultd.conf
    EnvironmentFile=-/tmp/.memfault.env
    # Generates .memfault.env if override key exists
    ExecStartPre=/usr/libexec/project-key-override-checker.sh
    ExecStart=
    ExecStart=/usr/bin/memfaultd --daemonize --config-file "${CONF_FILE}"
    
  • /usr/libexec/project-key-override-checker.sh
    #!/usr/bin/env bash
    
    set -u
    
    override_key_path="/home/root/.config/remarkable/memfault_project_key.conf"
    conf="/etc/memfaultd.conf"
    custom_override_conf="/tmp/.memfaultd-override.conf"
    env_file="/tmp/.memfault.env"
    
    rm -f "${env_file}"
    rm -f "${custom_override_conf}"
    
    if [ ! -e "${override_key_path}" ]; then
        exit 0
    fi
    
    # Key is expected to be 32 characters of alnum ([A-Za-z0-9])
    override_key="$(head -n 1 "${override_key_path}" | grep -Eo '^[[:alnum:]_-]+$')"
    if [ ! -z "${override_key}" ]; then
        sed "s/^\([[:blank:]]*\"project_key\"[[:blank:]]*:[[:blank:]]*\)\"[[:alnum:]]\+\"[[:blank:]]*,$/\1\"${override_key}\",/" "${conf}" > "${custom_override_conf}"
        echo "CONF_FILE=\"${custom_override_conf}\"" > "${env_file}"
    fi
    

@Eeems
Copy link
Contributor Author

Eeems commented Jun 6, 2024

@Eeems
Copy link
Contributor Author

Eeems commented Jun 6, 2024

/tmp/swupdate.cfg

globals :
{
  verbose = false;
  loglevel = 2;
  syslog = true;
};
download :
{
  retries = 3;
  timeout = 1800;
};
suricatta :
{
  confirm = 0;
  polldelay = 300;
  retry = 4;
  retrywait = 200;
  loglevel = 10;
  userid = 0;
  groupid = 0;
  max_artifacts = 1;
  url = "https://device.cloud.remarkable.com/api/v0/hawkbit";
  id = "...";
  tenant = "default";
  gatewaytoken = "...";
};
identify = (
  {
    name = "memfault__current_version";
    value = "3.11.2.5";
  },
  {
    name = "memfault__hardware_version";
    value = "reMarkable1";
  },
  {
    name = "memfault__software_type";
    value = "device";
  } );

I've snipped two things, as I don't know if they are generated on device or not.

@Eeems
Copy link
Contributor Author

Eeems commented Jun 6, 2024

https://github.com/sbabic/swupdate/blob/master/suricatta/server_hawkbit.c
This appears to be what consumes the settings to communicate with the server.

@Eeems
Copy link
Contributor Author

Eeems commented Jun 10, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant