Backup with rsync on qnap nas (architecture armel). Inside a private protected local network rsync (3.2.7) is running in daemon mode. Together with btrkbk to store snapshots. Debian 12 is the latest version of debian which supports my nas (qnap trs219p).

Having updated debian os, 2026-07, rsync stopped working with files bigger than 2GB – rsync error: file too large.
(dpkg -l | grep rsync shows: rsync_3.2.7-1+deb12u6)

Going back to version rsync_3.2.7-1+deb12u4 removed this error. (Possible background: debian maintainers backported the patches described here.)

Steps to downgrade from rsync patch version u6 to u4:

  • as root user:
    • apt-get install build-essential fakeroot devscripts
    • apt build-dep rsync
  • as normal user build deb package for rsync:
    • mkdir src; cd src
    • mkdir rsync3271u4; cd rsync3271u4
    • look up url of dsc file for rsync_3.2.7-1+deb12u4.dsc here (snapshot.debian.org)
    • dget DSC_URL
    • cd rsync-3.2.7
    • debuild -b -uc -us
  • as root user:
    • tell debian apt to pin version u4 of rsync
    • create file /etc/apt/preferences.d/rsync
    • content of this file:
      Package: rsync
      Pin: version 3.2.7-1+deb12u4
      Pin-Priority: 1000
    • finally install rsync u4 from local deb package
    • dpkg -i rsync3271u4/rsync_3.2.7-1+deb12u4_armel.deb

Environment: Tablet (Android 11, 4GB RAM, 8 cores + keyboard with touchpad),
IDE VS Code (code-server 4.7+Volar+Vetur Extended, displayed by Chrome 104) running inside Termux

Steps to get the web browser based IDE VS Code with code-server up and running:

  • Install Termux from F-Droid (terminal emulator and Linux environment app)
    • due to permission issues since android 10 the Termux app on Google Play Store is outdated (reference)
    • security settings on Android: allow installation of apk
    • open Termux console and run shell command pkg update to update all components of termux
  • Install NodeJS inside Termux:
    • pkg install nodejs-lts
      • in my case I got EACCESS errors in /data/data/com.termux […] cacache/tmp which were resolved by temporarily switching from nodejs-lts to nodejs and back again:
        pkg uninstall nodejs-lts
        pkg install nodejs
        • a true solution would be to chown files in tmp dir of npm to the current user:
          • npm get tmp shows the tmp directory of npm
          • id shows user and group id of current user (uid, gid)
          • chown -R 12345:12345 PATH_TO_TMP/tmp/
            chown -R 12345:12345 tmp/
        • but Termux runs as restricted user and cannot change ownership
      • code-server, currently (2022-09), requires nodejs-lts
  • Install dependencies to be able to build code-server
  • Use npm to install on global scope code-server
    • npm install -g code-server –unsafe-permissions (reference)
    • if code-server got installed but does not run because of missing modules (minimist, yauzl, yazl) then cd into /data/data/com.termux/files/usr/lib/node_modules/code-server/lib/vscode and run npm install –legacy-peer-deps (reference)
  • Run code-server
    • code-server
      • either edit $HOME/.config/code-server/config.yaml and set your password
      • or run code-server –auth none (reference)
    • open http://localhost:8080 with your web browser
    • install extensions Volar and Vetur extended from code-server web interface
  • Create a NuxtJS example app (reference)
    • use second session in Termux
      • open a second terminal inside Termux (keyboard shortcuts)ctrl+alt+c creates a new session
        • ctrl+alt+p or ctrl+alt+down arrow goes to previous session
        • ctrl+alt+n or ctrl+alt+up arrow goes to next session
        • ctrl+alt+right arrow opens session menu
        • (left arrow closes it; up/down switches sessions)
    • run yarn create nuxt-app hello-nuxt
      • this command does automatically install required packages
      • when asked:
        use java-script/packager yarn/no UI framework/no modules/no linting/no testing
        render universal (SSR / SSG)/deploy static/jamstack/no version control
      • cd into project directory hello-nuxt and run yarn dev
      • (later use yarn build and yarn start for production version;
        these commands are defined in the scripts section of file package.json.)
    • open http://localhost:3000
    • open project directory $HOME/hello-nuxt with explorer of code-server
      • edit pages/index.vue and save the changes
    • these changes, when saved, are immediately shown at http://localhost:3000
    • use copy and paste to replace index.vue by code of the NuxtJS hello world example code
    • open left pane of code sandbox at hello world example code and copy code of about.vue
    • create file about.vue inside explorer of code-server, paste code and save file

simple-code-editor is another example

  • goto home directory and generate the nuxt framework with command
    yarn create nuxt-app nuxt-example2
    • accept defaults when asked, just press enter, except Deployment target: use Static and no Version control
  • cd into this directory, cd nuxt-example2
  • run npm install simple-code-editor
  • with VS Code
    • hamburger menu on top left corner: File / Open Folder
      use folder nuxt-example2
    • open nuxt.config.js and add the line
      “simple-code-editor/nuxt”,
      inside the square brackets of modules: section
    • save nuxt.config.js
    • open pages/index.vue and edit the template section:
      • replace <Tutorial/> by
        <client-only>
        <CodeEditor value=”console.log(13)” width=”95%”
        :language_selector=”true” :languages=”[[‘cpp’,’C++’], [‘c’, ‘C’]]”></CodeEditor>
        </client-only>
      • save this file
      • use right click to delete Components/Tutorial.vue
  • go back to Termux console and run yarn dev
  • watch result with web browser, http://localhost:3000
  • to compile the final version run
    • yarn build
    • yarn generate
  • to show the content of folder dist/ at http://localhost:3000 run
    • yarn start
  • to Download the contents of the dist folder use VS Code
    • click on refresh in explorer “…”
    • right click on dist folder and select Download (only available with desktop browser; see ssh port forwarding below)
    • choose the target folder and confirm
  • to copy the dist folder to Android Documents folder (reference)
    • run termux-setup-storage
    • cp -R dist /sdcard/Documents/
    • mv /sdcard/Documents/dist/ /sdcard/Documents/code-editor2
  • this folder may be delivered by almost any simple webserver, e.g. Simple HTTP Server app on Android

Sometimes it is more comfortable to use a desktop web browser, which is possible by port forwarding with ssh.

  • open Termux console and install ssh by running pkg install openssh
  • edit /data/data/com.termux/files/usr/etc/ssh/sshd_config, e.g. with editor nano
    • add the line
      AllowTcpForwarding yes
  • use command whoami to display the linux user name used by android, e.g. u0_a250
  • set a password for this user with command passwd
  • make sure the android tablet is connected to local wifi and display the ip address with ifconfig
  • start sshd with command sshd (sshd of Termux listens on port 8022)
  • on the desktop pc run
    • ssh -p8022 -L3000:localhost:3000 -L8080:localhost:8080 u0_a123@192.168.123.123
      (replace u0_a123 with correct username and 192.168.123.123 with correct ip address)
    • open http://localhost:8080 and http://localhost:3000 with web browser

As a customer without cloud products volume licensing was done with a “normal” account of my organization: user@mydomain.xyz. Meanwhile a work or school account (WSA) is required. Reference.

Steps required, in my case, to change the existing account into a WSA account:

  • Use what is called by microsoft Internal admin takeover (reference)
  • (maybe the steps below depend on my first try to create a new account user@mydomainxyz.onmicrosoft.com account)
  • open https://powerbi.com/ and create an account with the same email address as the existing account
  • use this newly created account to open https://admin.microsoft.com/admintakeover (if asked during login wether private or business account use business account)
  • the next steps cause that the newly created account, user@mydomain.xyz, is assigned to mydomain.xyz and to the role global admin
  • you are instructed to create a dns txt entry at mydomain.xyz to verify your ownership of mydomain.xyz. (This txt dns entry can be removed after verification)
  • logged in at admin.microsoft.ch at settings/domains mydomain.xyz should be displayed as standard domain
  • now open microsoft volume licensing center, https://www.microsoft.com/Licensing/servicecenter/default.aspx and choose sign in with your work account, user@mydomain.xyz. Single sign on should work (if already logged in at admin.microsoft.com).
  • Existing licenses should be displayed. Message to upgrade account to WSA should be gone. Done!

windows 10 client: use symbolic links for Desktop, Documents and Downloads folders pointing to H: because the default install of https://www.linuxmuster.net/de/home/ uses local profile folders and network drive H: as home directory. The approach below creates this redirection of Desktop, Documents and Downloads semi automatically: all settings are made on the domain controller; if the user global-admin logs on to a workstation the symbolic links of all users which have already logged on to this workstation are created.

manage gpo by installing rsat on windows 10 (gpo and ad tools) with powershell:
Get-Command -Noun WindowsCapability
Get-WindowsCapability -Name RSAT* -Online
Get-WindowsCapability -Name RSAT* -Online | Select-Object -Property DisplayName, State
Get-WindowsCapability -Name RSAT.A* -Online | Add-WindowsCapability -Online
Get-WindowsCapability -Name RSAT.Group* -Online | Add-WindowsCapability -Online

use logon and logoff scripts (builtin gpo object sophomorix:default:school defines scripts at /var/lib/samba/sysvol/default-school/custom/windows/; create additional gpo object at global/management: sophomorix:global:management to define logon/logoff scripts for user global-admin)
User/Policies/Windows/Scripts

h: drive letter is mapped to home directory in linuxmuster, thus use
mklink /d Desktop H:\Desktop (same for Documents and Downloads). mklink requires either admin rights (elevated command prompt) or gpo policy for global-admin to allow creation of symbolic links.
Computer/Policies/Windows/Security/Local/User settings/create symbolic links

  • user scripts of normal user:
    • create H:\Desktop (same for Documents, Downloads)
    • robocopy content to H:
    • rename Desktop to Desktop.bak when logged off
      (until folder Desktop has been replaced by symlink Desktop)
    • give global admin access to main user folder
    • if symlink does not yet exist, copy content from H:\Desktop to Desktop during logon
  • logon script of global-admin
    • create symlink
  • startup script
    • truncate log file
@echo off
rem called by gpo object in schools/default-school (builtin)
rem User/Policies/Windows/Scripts
rem ################################################################
rem #          Run custom Logon-Script                             #
rem ################################################################
echo logon.bat %USERNAME% start >>c:\tmp\log.txt
if %USERNAME%==global-admin goto :ADMIN
C:
cd \Users\%USERNAME%
rem for %%d in (Videos) do (
for %%d in (Desktop Documents Downloads) do (
 if exist %%d (
  dir |find "%%d" |find "SYMLINKD"
  if not errorlevel 1 (
   if exist %%d.bak (
    if not exist H:\%%d mkdir H:\%%d
    robocopy %%d.bak H:\%%d /e /copy:DATSO /r:1 /w:3
    if not errorlevel 9 (
      attrib -r %%d.bak
      ren %%d. %%d.unused
      attrib -r -h -s %%d.unused\* /s /d
      rd %%d.unused /s /q
    ) else (
      attrib -r %%d.bak
      ren %%d.bak %%d.unused
      attrib -r -h -s %%d.unused\* /s /d
    )
   )
  ) else (
   if exist %%d.bak (
    robocopy %%d.bak %%d /e /copy:DATSO /r:1 /w:3
    attrib -r %%d.bak
    attrib -r -h -s %%d.bak\* /s /d
    rd %%d.bak /s /q
    if exist %%d.bak ren %%d.bak %%d.error
   )
   if exist H:\%%d robocopy H:\%%d %%d /e /copy:DATSO /r:1 /w:3
  )
 ) else (
   if exist %%d.bak (
    ren %%d.bak %%d
   ) else (
    mkdir %%d
   )
   if exist H:\%%d robocopy H:\%%d %%d /e /copy:DATSO /r:1 /w:3
 )
)
goto :ENDE
:ADMIN
:ENDE
@echo off
rem called by gpo object in schools/default-school (builtin)
rem User/Policies/Windows/Scripts
rem ################################################################
rem #          Run custom Logoff-Script                            #
rem ################################################################
echo logoff.bat %USERNAME% start >>c:\tmp\log.txt
if %USERNAME%==global-admin goto :ADMIN
C:
cd \Users\%USERNAME%
icacls \Users\%USERNAME% |find "global-admin" |find "(F)"
if errorlevel 1 (icacls \Users\%USERNAME% /grant "linuxmuster\global-admin":"(NP)(F)" /c)
rem for %%d in (Videos) do (
for %%d in (Desktop Documents Downloads) do (
 if exist %%d (
  dir |find "%%d" |find "SYMLINKD"
  if errorlevel 1 (
   if not exist H:\%%d mkdir H:\%%d
   robocopy %%d H:\%%d /e /copy:DATSO /r:1 /w:3
   if not errorlevel 9 (
    attrib -r %%d
    ren %%d %%d.bak
    attrib -r -h -s %%d.bak\* /s /d
    rd %%d.bak /s /q
   ) else (
    attrib -r %%d
    ren %%d %%d.bak
    attrib -r -h -s %%d.bak\* /s /d
   )
  )
 )
)

goto :ENDE
:ADMIN
:ENDE
echo logoff.bat %USERNAME% stop >>c:\tmp\log.txt
@echo off
rem called by gpo object in global/management (not builtin)
rem User/Policies/Windows/Scripts
rem ################################################################
rem #          Run custom Logon-Script                             #
rem ################################################################
echo logon.bat %USERNAME% start >>c:\tmp\log.txt
if %USERNAME%==global-admin goto :ADMIN
goto :ENDE
:ADMIN
rem user global-admin has symlink create permission in global gpo
rem Computer/Policies/Windows/Security/Local/User permissions: create symbolic links
C:
cd \Users
rem create symlinks in user directories pointing to H:\DIRNAME **only** if
rem  1) user global admin has access to user directory
rem  2) folders Desktop, Documents and/or Downloads do not exist
rem all other work is done by logon/logoff scripts of normal users
for /d %%u in (*) do (
 dir %%u
 if not errorlevel 1 (
  cd \Users\%%u
  for %%d in (Desktop Documents Downloads) do (
   if not exist %%d (
    mklink /d %%d H:\%%d
    if not errorlevel 1 (echo mklink ok %%u\%%d >>c:\tmp\log.txt) else (echo mklink failed %%u\%%d >>c:\tmp\log.txt)
   )
  )
  cd \Users
 )
)

:ENDE
echo logon.bat %USERNAME% stop >>c:\tmp\log.txt
@echo off
rem called by gpo object in global/management (not builtin)
rem User/Policies/Windows/Scripts
rem ################################################################
rem #          Run custom Logoff-Script                            #
rem ################################################################
echo logoff.bat %USERNAME% start >>c:\tmp\log.txt
if %USERNAME%==global-admin goto :ADMIN
goto :ENDE
:ADMIN
:ENDE
echo logoff.bat %USERNAME% stop >>c:\tmp\log.txt
@echo off
rem called by gpo object in schools/default-school (builtin)
rem Computer/Policies/Windows/Scripts (running as machine account)
rem ################################################################
rem #          Run custom Systemstart-Script                       #
rem ################################################################
rem overwrite existing logfile that is, clear log at startup
if not exist C:\tmp mkdir c:\tmp
echo sysstart %USERNAME% >C:\tmp\log.txt
:ENDE

x

rsync update troubles on debian 12

x

rsync update troubles on debian 12

x

rsync update troubles on debian 12

x

rsync update troubles on debian 12

x

rsync update troubles on debian 12

This post collects observations when using MAix GO board with Arduino IDE, call Maixduino.

Macros how special pins on board MAix GO are called, can be found in pins_arduino.h of MAix GO., like PIN_KEY_PRESS which has an external pull up resistor (see schematic).

When testing example code of libraries function Serial.begin() seems to need a little time to initialize. Console output worked after adding 300mS delay. (How much is the minimal delay required?):

Serial.begin(115200);
delay(300);

Below libraries are listed which have example code that compiles and runs with MAix GO board (maybe the code needs minimal modification like replacing BUILTIN_LED by LED_BUILTIN; use compiler error messages – Preferences/Show verbose output during compilation):

  • WiFiEsp (included with Maixduino board addon of Arduino IDE)
  • RingBuffer by locoduino (installable with Arduino Library Manager)
    (Maybe EspRingBuffer coming as part of of WiFiEsp bundled with Maixduino, folder src/utility, is of interest as well.)
  • ArduinoJson by Benoît Blanchan (Arduino Library Manager)
  • ArduinoMqtt by Oleg Kovalenk which is based on eclipse paho (Arduino Library Manager)
    Use the example ConnectEsp8266WiFiClient and replace: ESP8266WiFi.h by WiFiEsp.h (included in Maixduino), WiFiClient by WiFiEspClient, ESP.reset() by WiFi.reset() and copy WiFi setup code from example of WiFiEsp. – If not properly initialized might stop k210 cpu with illegal instruction.
  • pubsubclient by Nick O’Leary (Arduino Library Manager). Same remarks as shown above (ArduinoMqtt).

According to Kendryte K210 datasheet (available here) the speed of the 4 uart interfaces of K210 can run with up to 5 MHz baud rate. Communication with esp8285 used as wifi chip runs by default with 115200 baud and seems to run with 2000000 baud as well. (Tested with sketch Examples/Maix Go/WiFiEsp/Test/EspDebug: use command AT+UART_CUR:2000000,8,1,0,1). AT command reference is here. Using the _CUR command means that after reboot the default settings get restored. Storing the settings permanently bears the risk to make esp8266 inaccessible (if not reflashed).

Source of AT command firmware is here at github, if you select tag v2.2.1 (examples/at). – Install compiler (folder dist in https://github.com/noduino/xtensa-toolchain or http://domoticx.com/sdk-esp8266-xtensa-architecture-toolchain/) and add it to path. Inside SDK folder copy folder examples/at to root folder of SDK. Run script gen_misc and choose: boot_v1.2+, user1.bin (or user2.bin), spi 40MHz, spi DOUT, 1024KB (512KB+512KB); result is in folder bin/. Uploading to esp8285 would require to shorten ground and the pad GPIO0 in the corner of the antenna connector (info from sipeed forum).

notes about using esptool.py to flash firmware (hide expanded file):
to verify size of flash
python utils/esptool.py --port /dev/cu.usbserial-143110 --baud 115200 flash_id

nodemcu board, 4MB=32000kbit, successfully flashed with
python utils/esptool.py --port /dev/cu.usbserial-143110 --baud 115200 write_flash 0x00000 bin/eagle.flash.bin 0x10000 bin/eagle.irom0text.bin 0x7E000 bin/blank.bin 0x3FE000 bin/blank.bin 0x3FC000 bin/esp_init_data_default.bin 
(tested by konsole of arduino ide; firmware has default baud rate of 115200; boot messages are sent with 74880 baud ->technical reference of esp8266)

esp8285, 1MB=4096kbit, should be flashable with
python utils/esptool.py --port /dev/cu.usbserial-143110 --baud 115200 write_flash 0x00000 bin/eagle.flash.bin 0x10000 bin/eagle.irom0text.bin 0x7E000 bin/blank.bin 0xFE000 bin/blank.bin 0xFC000 bin/esp_init_data_default.bin

To use WiFiEsp lib with 2000000 baud without setting it permanently WiFiEsp has to be patched: by default WiFi.init(&Serial1) function does call AT+RST which reboots esp8285. In patched version you can call WiFi.init(&Serial1, false) to avoid this reboot:

WiFiEsp_disable_at_rst_in_init.diff (hide expanded diff file):
diff -ur orig/WiFiEsp.cpp new/WiFiEsp.cpp
--- orig/WiFiEsp.cpp	2019-07-15 17:14:20.000000000 +0200
+++ new/WiFiEsp.cpp	2019-08-07 11:32:14.000000000 +0200
@@ -33,8 +33,14 @@
 
 void WiFiEspClass::init(Stream* espSerial)
 {
+	init(espSerial, true);
+}
+
+
+void WiFiEspClass::init(Stream* espSerial, bool run_at_rst)
+{
     LOGINFO(F("Initializing ESP module"));
-	EspDrv::wifiDriverInit(espSerial);
+	EspDrv::wifiDriverInit(espSerial, run_at_rst);
 }
 
 
diff -ur orig/WiFiEsp.h new/WiFiEsp.h
--- orig/WiFiEsp.h	2019-07-15 17:14:20.000000000 +0200
+++ new/WiFiEsp.h	2019-08-07 11:33:01.000000000 +0200
@@ -51,6 +51,8 @@
 	*/
 	static void init(Stream* espSerial);
 
+	static void init(Stream* espSerial, bool do_at_rst);
+
 
 	/**
 	* Get firmware version
diff -ur orig/utility/EspDrv.cpp new/utility/EspDrv.cpp
--- orig/utility/EspDrv.cpp	2019-07-15 17:14:20.000000000 +0200
+++ new/utility/EspDrv.cpp	2019-08-07 12:04:48.000000000 +0200
@@ -70,8 +70,15 @@
 uint8_t EspDrv::_remoteIp[] = {0};
 
 
+
 void EspDrv::wifiDriverInit(Stream *espSerial)
 {
+	wifiDriverInit(espSerial, true);
+}
+
+
+void EspDrv::wifiDriverInit(Stream *espSerial, bool run_at_rst)
+{
 	LOGDEBUG(F("> wifiDriverInit"));
 
 	EspDrv::espSerial = espSerial;
@@ -95,7 +102,7 @@
 		return;
 	}
 
-	reset();
+	reset(run_at_rst);
 
 	// check firmware version
 	getFwVersion();
@@ -114,13 +121,23 @@
 }
 
 
+
 void EspDrv::reset()
 {
+	reset(true);
+}
+
+
+void EspDrv::reset(bool run_at_rst)
+{
 	LOGDEBUG(F("> reset"));
 
-	sendCmd(F("AT+RST"));
-	delay(3000);
-	espEmptyBuf(false);  // empty dirty characters from the buffer
+	if(run_at_rst)
+	{
+		sendCmd(F("AT+RST"));
+		delay(3000);
+		espEmptyBuf(false);  // empty dirty characters from the buffer
+	}
 
 	// disable echo of commands
 	sendCmd(F("ATE0"));
diff -ur orig/utility/EspDrv.h new/utility/EspDrv.h
--- orig/utility/EspDrv.h	2019-07-15 17:14:20.000000000 +0200
+++ new/utility/EspDrv.h	2019-08-07 11:38:57.000000000 +0200
@@ -123,6 +123,9 @@
     static void wifiDriverInit(Stream *espSerial);
 
 
+    static void wifiDriverInit(Stream *espSerial, bool run_at_rst);
+
+
     /* Start Wifi connection with passphrase
      *
      * param ssid: Pointer to the SSID string.
@@ -279,6 +282,8 @@
 	static bool ping(const char *host);
     static void reset();
 
+    static void reset(bool do_at_rst);
+
     static void getRemoteIpAddress(IPAddress& ip);
     static uint16_t getRemotePort();
 

To be continued.