Compare commits

...
34 Commits
Author SHA1 Message Date
Joachim Wiberg 406dbfdff4 Update release date for v24.04.2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 15:50:12 +02:00
Joachim WibergandTobias Waldekranz 9d7817356f statd: support for enabling DEBUG() logs with env, like confd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 16c21f0da8 doc: update ChangeLog for v24.04.2 patch release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz aa20f29b36 confd: fix missing /etc/resolv.conf after 'no system'
When a CLI user performs the following command, the DNS resolver was
left in an undefined state.

    admin@infix-00-00-00:/config/> no system
    admin@infix-00-00-00:/config/> leave
    admin@infix:/>

The avahi-daemon reported the missing /etc/resolv.conf and the fix is to
ensure `resolvconf -u` runs on every major change ot ietf-system, even
if there is no new resolv.conf to roll in.  At bootstrap this has been
handled by another mechanism so has not been seen by most users.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz c6b818d0bc confd: fix error handling for sr_get_data()
The sr_get_data() API may return SR_ERR_OK and still set the cfg pointer
to NULL!  This happens when, e.g., executing 'no system' from the CLI.

This patch adds a check for this in all occurrences of sr_get_data().

Also, in ietf-routing.c there was *no* error handling for this API, this
required some restructuring to ensure a FILE *fp was closed properly in
all cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 89c9a12db2 confd: on failure to load startup-config, reset and regroup
With the sysrepo patch from the previous commit, we can now properly
detect if a callback failed to apply its changes in SR_EV_DONE.  When
this occurs the system may be in an undefined state, so we must try
to recover it before loading failure-config.

This patch tries to perform a factory-default RPC, which is an Infix
specifc RPC that does "copy factory-config running-config".  We give
sysrepocfg some time to clean up any stale SHM connections before we
do a hard scratch of the db state and restart sysrepo-plugind.

Fixes #429

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 9df97d9a1b patches/sysrepo: add support for non-zero exit code from syrepocfg
This local patch of sysrepo adds support for detecting non-zero return
code from sysrepo callbacks during SR_EV_DONE, which upstream sysrepo
currently, as of v2.2.105, discards.

With this change failure to load startup-config results in the system
detecting the failure applying failure-config instead.

Fixes #429

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz d0cfe429c4 confd: fix regression, loss of admin account after upgrade to v24.04
Fix regression introduced in 3f87945, which tries to map a user to an
existing home directory.  The root cause for the problem is basically an
invalid check of the /home/admin UID being in use by any system account
or not.  This patch uses the same check used by the BusyBox adduser
command.

In addition to the uid-already-in-use fix, several other checks have
been added to ensure we do not end up with an invalid system state:

 - If reusing an existing /home/admin fails in the 'adduser admin'
   command, wipe out /home/admin and retry adding the user cleanly
 - Always delete any group with the same name before trying to add
   the user, regardless if /home/$user exists or not, this prevents
   issues with stale group records if we end up failing to load the
   startup-config and need to load failure-config
 - For the same reason (failure-config), make sure to always clean
   up any stale user in the retry step.  The same step is used when
   there is a uid:gid mismapping (the original bug)

Fixes #428

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz adf37394f4 confd: follow-up to 2412fff3, simplify chown of startup-config
Instead of having a chown process started by Finit in runlevel S, we can
just chown in the confd load script instead.

Issue #415

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz bc020436e7 confd: increased severity for log messages caught on stdout/stderr
Error messages from system() calls, like adduser, should be logged with
severity LOG_ERR to not arrive out of sequence with ERROR() messages.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz ad8a74fa7b confd: minor, fix variable shadowing
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 3315a46423 confd: minor, skip shell update when deleting user
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz 334d222f7c confd: minor, logging cleanup
- Drop unnecessary \n
 - Drop needless ERROR() message triggered when deleting users

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz d624203815 confd: minor, match syslog tag with other log messages
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Joachim WibergandTobias Waldekranz ab21eff6c8 confd: minor, use initial hostname from /etc/os-release as fallback
Instead of hard-coding the fallback hostname we can now use the one
generated to /etc/os-release (for netbrowse).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-13 11:42:27 +02:00
Jon-Olov Vatnandjovatn a05e28d349 Updating text after feedback.
I found similar error in other parts of the doc, as well
as some typos, and fixed them there too.

[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn 81c8f1c944 Fixing more typos.
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn d039d9fc2b Fix typo.
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn e1dd636ed0 Update link list and fixing typo.
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn c4236eaa80 Yet another try for anchors for cross-references 2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn a8c47779a2 New try for explicit anchors for cross-references
[skip ci]
2024-05-13 07:50:34 +02:00
Jon-Olov Vatnandjovatn 3178d5aae4 Adding script examples for production tests
- reading out eeprom/vpd data
- led testing
- power supply testing
- ethernet port test (example for looping ports)

[skip ci]
2024-05-13 07:50:34 +02:00
Tobias Waldekranz e63256edbb cn9130-crb: Document bootstrapping procedure 2024-05-07 15:34:47 +02:00
Tobias Waldekranz 68a0b289d2 board/aarch64: Separate board specific documentation
This should make it easier to find what you're after as the number of
supported boards increase.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 8a7eb80878 cn9130-crb: Set Infix default password
Since we don't have any VPD defined on this board, supply a default
password hash via the device tree instead.

Also, specify the path to external USB port, so that Infix will pick
it up in ietf-hardware.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 473d48097c cn9130-crb: Enable eth2, avoid polling of SFP io lines
Provide a patched device tree that:

- Uses the correct phy-mode for eth2, allowing it to be probed
  properly

- Wires up the interrupt signal to the GPIO expander, so that the SFP
  cage's I/O lines can be configured as interrupts, rather than having
  to poll them
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 50a9bba1c7 board/common: fdisk: Allow reformatting of disks
Assume that the caller always want to create a new partition table,
even in scenarios where one already exists. This allows devices to be
reprovisioned with a newer image, for example.

Fixes #394
2024-05-07 15:34:47 +02:00
Tobias Waldekranz 21ab842357 board/common: Fix incorrect path to /etc/partition-uuid
While we're here, fix some whitespace nits.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz b5abcc8af9 cn9130-crb: Add a small bootdelay in U-Boot
This is not a production target, so we choose the more developer
friendly option of allowing the boot process to be interrupted.

Also, remove the old update cruft and rely on Marvell's `bubt`
instead.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz ca968c7d87 cn9130-crb: Switch to using SPI FLASH for bootloader storage
The BootROM wants the bootloader to be located on LBA1, which is not
ideal when using a GPT to describe the partition table.

Make sure the `bubt` command targets SPI by default.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz d96f3ae2e9 defconfig: cn9130_crb_boot: Pin ATF version after Buildroot update
Buildroot's default ATF version changed from 2.9 to 2.10 when we
upgraded to 24.02.x. This meant that our patches were not applied,
which broke the build.

Take a conservative approach for now, and just pin the ATF version to
the known-good 2.9 series.
2024-05-07 15:34:47 +02:00
Tobias Waldekranz f45e1d57a0 defconfig: cn9130_crb_boot: Restore image signing functionality
During the addition of multi-key support to RAUC and U-Boot, the
bootloader defconfig for CN9130 CRB was overlooked, which meant that
the Infix specific U-Boot hooks never ran, thereby ultimately breaking
the build.

Restore the required options to build in the dev-key by default.
2024-05-07 15:34:47 +02:00
Joachim Wiberg f5b0f37386 confd: rename 10-infix-system.json -> 10-infix-services.json
Mislabled from the start, the file holds default services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-05 18:20:03 +02:00
Joachim Wiberg f0205b0a35 board/common: document reserved syslog facilities
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-05-05 18:15:03 +02:00
32 changed files with 1104 additions and 212 deletions
+4 -64
View File
@@ -1,67 +1,7 @@
aarch64
=======
Microchip SparX-5i PCB135 (eMMC)
--------------------------------
At present, only FIT images are supported via the SparX-5i eval
board's U-Boot, which must contain a valid load address. If you are
using this board, after selecting your base configuration, run the
following command to supplement the existing config with the required
FIT options:
make board-enable-sparx-fit
### Unbricking
1. Don't load a corrupt bootloader to begin with
2. Done
If, for some reason, you didn't manage to follow step 1, you can use
the `FLASH_PROG`(`J4`) connector on the board to access the SPI flash
directly.
Using a [Bus Blaster][BB3] in combination with [dangerspi][dangerspi],
you can load a new bootloader. The schematic below details how to
connect the Bus Blaster to the board, but the concept should be
portable to any debugger/device based around an FTDI2232 chip.
```
Bus Blaster: FLASH_PROG (J4):
.---. .---.
VTG >o o| VTG SCK >o o| GND
TRST |o o| GND MISO |o o| #RESET_FLASH
TDI |o o| GND o o| 3V3
TMS |o o| GND #CS |o o| #SYSRESET
TCK o o| GND MOSI |o o| GND
RTCK o o| GND '---'
TDO |o o| GND
TSRST |o o| GND
DBGRQ |o o| GND
DBGACK |o o| GND
'---'
```
| Bus Blaster | FLASH_PROG |
|-------------|----------------|
| `VTG` | `3V3` |
| `GND` | `GND` |
| | |
| `VTG` | `#RESET_FLASH` |
| `GND` | `#SYSRESET` |
| | |
| `TDI` | `MOSI` |
| `TMS` | `#CS` |
| `TCK` | `SCK` |
| `TDO` | `MISO` |
With the cable in place, build U-Boot with the correct configuration:
make fireant_boot_defconfig && make
To flash it to the board, connect the cable to `J4` and run:
make board-sparx-flash-uboot
[BB3]: http://dangerousprototypes.com/docs/Bus_Blaster#Bus_Blaster_v3
[dangerspi]: https://github.com/wkz/dangerspi
Board Specific Documentation
----------------------------
- [Marvell CN9130-CRB](cn9130-crb/)
- [Microchip SparX-5i PCB135 (eMMC)](sparx5-pcb135/)
+132
View File
@@ -0,0 +1,132 @@
Marvell CN9130-CRB
==================
## Build instructions
### Bootloader
Build the bootloader from the supplied `defconfig`. It might be useful
to build in a separate output directory if you want to build Infix
from the same working tree later:
make O=$(pwd)/x-cn9130-boot cn9130_crb_boot_defconfig
cd x-cn9130-boot
make
The artifact of interest is called `flash-image.bin`, which will be
located in the `images/` directory once the build completes.
### Infix
> If you do not want to build Infix from source, feel free to use a pre-built [release]
The standard `aarch64_defconfig` is compatible with this board:
make O=$(pwd)/x-aarch64 aarch64_defconfig
cd x-aarch64
make
Two artifacts from the `images/` directory of this build are required
to provision a new board:
- `rootfs.itb`: Netbootable image
- `infix-aarch64.pkg`: Standard upgrade bundle
## Provisioning
The overall provisioning flow, in which each step in described in
details in the following sections, is as follows:
- Strap board to boot from SPI FLASH
- Load `flash-image.bin` over UART
- Burn `flash-image.bin` to SPI FLASH
- Netboot `rootfs.itb`
- Run Infix's built-in provisioning script
- Reboot, now booting from the primary partition of the SD-card
#### Strap Board to Boot from SPI FLASH
By default, the board is strapped to boot from eMMC. However, Infix
assumes that the board will boot from SPI FLASH. Therefore we have to
ensure that the DIP switches of `SW2` on the board selects a
`BOOT_MODE` of `0x32`, meaning that the switches on positions 4, 3,
and 1 should be enabled (i.e. these need to be tied to ground):
```
.-----. .-----. .-----.
| | | | | PWR |
| SIM | | uSD | | |
| | | | '-----'
'-----' '-----'
|
v
.-----. .-----.
| SW1 | | SW2 |
'-----' '-----'
.--------------------------.
| |
| |
| CN9130 |
```
#### UART Boot U-Boot
Make sure that:
- [mvebu64boot] is installed and available in your shell's `$PATH`
- No other program is attached to `ttyUSB0`
- No power is applied to the board
1. Start `mvebu64boot`:
mvebu64boot -b /path/to/flash-image.bin /dev/ttyUSB0
2. Apply power
As soon as `mvebu64boot` completes, attach to the serial port,
e.g. using `screen(1)`, or `console(1)` and stop the normal boot
process by hitting any key.
#### Burn U-Boot to SPI FLASH
Make sure that:
- `eth1` is connected to a machine which serves `flash-image.bin` over
TFTP
- U-Boot can reach the TFTP server. If the neighboring machine is also
set up as a DHCP server, simply run the command `dhcp -`
To burn the bootloader to SPI FLASH, run the `bubt` command:
bubt flash-image.bin
Once the command completes, reset the board to verify that it can now
boot unassisted:
reset
#### Boot up `rootfs.itb`
U-Boot will automatically fallback to netboot since the SD-card is
still blank. Make sure that the PC provides the path to `rootfs.itb`
in DHCP option 67 ("bootfile").
#### Install Firmware
Login as `admin`/`admin`, setup networking to the PC, ensure that the date on
the device is reasonably correct, and run the provisioning script:
admin@infix:~$ sudo -i
root@infix:~$ udhcpc -i e28
root@infix:~$ date -us YYYY-MM-DD
root@infix:~$ /libexec/infix/prod/provision tftp://<PC-IP>/infix-aarch64.pkg /dev/mmcblk0
After successful completion, the device is fully provisioned. On the
next boot, the device will boot of its own accord from the primary
SD-card partition.
> If possible, serve `infix-aarch64.pkg` over HTTP instead, as
> libcurl's TFTP implementation is quite slow.
[release]: https://github.com/kernelkit/infix/releases
[mvebu64boot]: https://github.com/addiva-elektronik/mvebu64boot
@@ -16,36 +16,7 @@ run ixboot
";
boot_targets = "mmc1";
ethprime = "eth1";
/* Uncomment this if you're debugging U-Boot
*
* This will allow you to break out of the
* normal boot flow and into the interactive
* console.
*
* To upgrade U-Boot itself, simply set the
* `bootfile` variable to the path of
* `flash-image.bin` on your TFTP server, then
* issue `run ixupgradeboot`.
*/
/* bootdelay = "2"; */
/* ixupgradeboot = " */
/* dhcp */
/* setexpr fileblks ${filesize} + 0x1ff */
/* setexpr fileblks ${fileblks} / 0x200 */
/* mmc dev 1 */
/* part start mmc 1 boot bootstart */
/* part size mmc 1 boot bootsize */
/* mmc erase ${bootstart} ${bootsize} */
/* mmc write ${fileaddr} ${bootstart} ${fileblks} */
/* "; */
bootdelay = "1";
};
};
};
/* &cp0_eth0 { */
/* phy-mode = "10gbase-r"; */
/* }; */
@@ -1,4 +1,6 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi cn9130-crb-env.dtsi"
CONFIG_SYS_PROMPT="(cn9130-crb) "
CONFIG_ENV_IS_NOWHERE=y
# CONFIG_ENV_IS_IN_MMC is not set
CONFIG_MVEBU_SPI_BOOT=y
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Marvell International Ltd.
*/
#include "cn9130-crb.dtsi"
/ {
model = "Marvell Armada CN9130-CRB-A";
chosen {
infix {
/* "admin" */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
usb-ports = <&cp0_usb3_1>;
usb-port-names = "USB";
};
};
};
&cp0_pcie0 {
status = "okay";
num-lanes = <4>;
num-viewport = <8>;
/* Generic PHY, providing serdes lanes */
phys = <&cp0_comphy0 0
&cp0_comphy1 0
&cp0_comphy2 0
&cp0_comphy3 0>;
iommu-map =
<0x0 &smmu 0x480 0x20>,
<0x100 &smmu 0x4a0 0x20>,
<0x200 &smmu 0x4c0 0x20>;
iommu-map-mask = <0x031f>;
};
&cp0_usb3_0 {
status = "okay";
usb-phy = <&cp0_usb3_0_phy0>;
phy-names = "usb";
};
&cp0_usb3_1 {
status = "okay";
usb-phy = <&cp0_usb3_0_phy1>;
phy-names = "usb";
};
&cp0_eth2 {
status = "okay";
phy-mode = "2500base-x";
};
&cp0_pinctrl {
cp0_expander0_pins: cp0-expander-pins-0 {
marvell,pins = "mpp39";
marvell,function = "gpio";
};
};
&expander0 {
pinctrl-names = "default";
pinctrl-0 = <&cp0_expander0_pins>;
interrupt-parent = <&cp0_gpio2>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells=<2>;
microchip,irq-mirror;
};
+64
View File
@@ -0,0 +1,64 @@
Microchip SparX-5i PCB135 (eMMC)
================================
At present, only FIT images are supported via the SparX-5i eval
board's U-Boot, which must contain a valid load address. If you are
using this board, after selecting your base configuration, run the
following command to supplement the existing config with the required
FIT options:
make board-enable-sparx-fit
## Unbricking
1. Don't load a corrupt bootloader to begin with
2. Done
If, for some reason, you didn't manage to follow step 1, you can use
the `FLASH_PROG`(`J4`) connector on the board to access the SPI flash
directly.
Using a [Bus Blaster][BB3] in combination with [dangerspi][dangerspi],
you can load a new bootloader. The schematic below details how to
connect the Bus Blaster to the board, but the concept should be
portable to any debugger/device based around an FTDI2232 chip.
```
Bus Blaster: FLASH_PROG (J4):
.---. .---.
VTG >o o| VTG SCK >o o| GND
TRST |o o| GND MISO |o o| #RESET_FLASH
TDI |o o| GND o o| 3V3
TMS |o o| GND #CS |o o| #SYSRESET
TCK o o| GND MOSI |o o| GND
RTCK o o| GND '---'
TDO |o o| GND
TSRST |o o| GND
DBGRQ |o o| GND
DBGACK |o o| GND
'---'
```
| Bus Blaster | FLASH_PROG |
|-------------|----------------|
| `VTG` | `3V3` |
| `GND` | `GND` |
| | |
| `VTG` | `#RESET_FLASH` |
| `GND` | `#SYSRESET` |
| | |
| `TDI` | `MOSI` |
| `TMS` | `#CS` |
| `TCK` | `SCK` |
| `TDO` | `MISO` |
With the cable in place, build U-Boot with the correct configuration:
make fireant_boot_defconfig && make
To flash it to the board, connect the cable to `J4` and run:
make board-sparx-flash-uboot
[BB3]: http://dangerousprototypes.com/docs/Bus_Blaster#Bus_Blaster_v3
[dangerspi]: https://github.com/wkz/dangerspi
@@ -0,0 +1,10 @@
Reserved facilities for logging in various subsystems:
- local0: rauc
- local1: containers
- local2:
- local3:
- local5:
- local6: reserved
- local7: nginx
+4 -4
View File
@@ -1,7 +1,7 @@
#!/bin/sh
set -e
. /etc/partion-uuid
. /etc/partition-uuid
disk=$1
bootoffs=$2
@@ -28,11 +28,11 @@ else
fi
sgdisk \
-o \
-Z \
-n1:${bootoffs}:+${bootsize} -t1:8301 -c1:boot \
-n2::+${auxsize} -t2:8301 -c2:aux -u2:${AUX_UUID}\
-n2::+${auxsize} -t2:8301 -c2:aux -u2:${AUX_UUID} \
-n3::+${imgsize} -t3:8300 -c3:primary -u3:${PRIMARY_UUID} \
-n4::+${imgsize} -t4:8300 -c4:secondary -u4:${SECONDARY_UUID}\
-n4::+${imgsize} -t4:8300 -c4:secondary -u4:${SECONDARY_UUID} \
-n5::+${cfgsize} -t5:8302 -c5:cfg \
-n6:: -t6:8310 -c6:var \
-p \
+4 -2
View File
@@ -16,6 +16,8 @@ BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
# BR2_TARGET_ROOTFS_TAR is not set
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.9"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="t9130"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
@@ -36,8 +38,8 @@ BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
# SIGN_ENABLED is not set
DISK_IMAGE=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
DISK_IMAGE_BOOT_BIN=y
DISK_IMAGE_BOOT_DATA="${BINARIES_DIR}/flash-image.bin"
DISK_IMAGE_BOOT_OFFSET=0x00200000
+20
View File
@@ -4,6 +4,25 @@ Change Log
All notable changes to the project are documented in this file.
[v24.04.2][] - 2024-05-15
-------------------------
### Changes
- Add small delay in U-Boot to allow stopping boot on reference boards
- Document how to provision the bootloader and Infix on a blank board
- Use initial hostname from `/etc/os-release` as configuration fallback
### Fixes
- Fix build regressions in `cn9130_crb_boot_defconfig` caused by upgrade
to Buildroot v2024.02 and recent multi-key support in RAUC and U-Boot
- Fix provisioning script after changes to make GRUB loading more robust
- Fix missing `/etc/resolv.conf`, as noticed by `avahi-daemon`, when a
user calls `no system` from the CLI
- Fix #428: loss of admin account after upgrade to v24.04
- Fix #429: failing to load `startup-config` does not trigger the fail
secure mode, causing the system to end up in an undefined state
[v24.04.1][] - 2024-05-03
-------------------------
@@ -862,6 +881,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.04.0...HEAD
[v24.04.2]: https://github.com/kernelkit/infix/compare/v24.04.1...v24.04.2
[v24.04.1]: https://github.com/kernelkit/infix/compare/v24.04.0...v24.04.1
[v24.04.0]: https://github.com/kernelkit/infix/compare/v24.02.0...v24.04.0
[v24.02.0]: https://github.com/kernelkit/infix/compare/v23.11.0...v24.02.0
+454 -7
View File
@@ -331,6 +331,58 @@ admin@infix.local%eth0's password: *****
~$
```
### Controlling LEDs for Production Tests
As part of production testing, LED verification is often expected to
be performed. Infix uses standard [Linux support for LED
management][6], where LEDs appear in the file system under
/sys/class/leds and can be controlled using *echo* command. `sudo`
privileges are required.
When interacting with LEDs this way, first disable the Infix *iitod*
daemon to avoid conflicting LED control.
```
~$ ssh admin@example.local 'initctl stop iitod'
```
Then run the test, e.g., visually control that a red LED labeled
'LAN' is working.
```
~$ ssh admin@example.local 'echo none | sudo tee /sys/class/leds/red\:lan/trigger'
~$ ssh admin@example.local 'echo 1 | sudo tee /sys/class/leds/red\:lan/brightness'
```
To turn off the same LED, run the following commands.
```
~$ ssh admin@example.local 'echo none | sudo tee /sys/class/leds/red\:lan/trigger'
~$ ssh admin@example.local 'echo 0 | sudo tee /sys/class/leds/red\:lan/brightness'
```
When done with LED testing, enable Infix *iitod* daemon again.
```
~$ ssh admin@example.local 'initctl start iitod'
```
### Reading Power Feed Status for Production Tests
As part of production tests, verification of Power Feed sensors is
often expected to be performed. Infix uses standard [Linux support for
Power management][7], where power sources appear in the file system
under /sys/class/power_supply. The following example reads status of
two power supplies named *pwr1* and *pwr2*.
```
~$ ssh admin@example 'cat /sys/class/power_supply/pwr1/online'
1
~$ ssh admin@example 'cat /sys/class/power_supply/pwr2/online'
0
~$
```
Here, only *pwr1* happened to have power.
## Examples using SSH and sysrepocfg
@@ -346,10 +398,10 @@ See [sysrepocfg][4] for information. Examples below will utilize
- `sysrepocfg -I FILE -fjson -d DATABASE` to import/write a JSON
formatted configuration file to the specificed database.
formatted configuration file to the specified database.
- `sysrepocfg -E FILE -fjson -d DATABASE` to edit/merge JSON formatted
configuration in FILE with the specificed database.
- `sysrepocfg -R FILE -fjson` to execute remote procdure call (RPC) defined in
configuration in FILE with the specified database.
- `sysrepocfg -R FILE -fjson` to execute remote procedure call (RPC) defined in
FILE (JSON formatted).
- `sysrepocfg -X -fjson -d DATABASE -x xpath` to read configuration or
status from specified database.
@@ -360,7 +412,7 @@ configuration. Exporting (-X) could operate on configuration (e.g.,
`-d running`) or status (`-d operational`).
Some commands require a file as input. In examples below we assume
it been transfered to Infix in advance, e.g. using `scp` as shown below.
it been transferred to Infix in advance, e.g. using `scp` as shown below.
```
~$ cat file.json
@@ -388,7 +440,7 @@ it been transfered to Infix in advance, e.g. using `scp` as shown below.
```
See [Factory Reset](#factory-reset) for another (simpler) alternative.
If you only wish to copy factory config to running config the
If it is only wished to copy factory config to running config the
following RPC is available
```
@@ -601,7 +653,7 @@ on interface *e0*.
~$
```
### Backup Configuration Using sysrepocfg And scp
### <a id="backup"></a> Backup Configuration Using sysrepocfg And scp
Displaying running or startup configuration is possible with
`sysrepocfg -X`, as shown below.
@@ -637,7 +689,7 @@ startup configuration (not running).
~$
```
### Restore Configuration Using sysrepocfg and ssh/scp
### <a id="restore"></a> Restore Configuration Using sysrepocfg and ssh/scp
To restore a backup configuration to startup, the simplest way is to
@@ -688,7 +740,402 @@ An alternative is to write it to a temporary file, and use `sysrepocfg
~$
```
### Read Out Hardware Information Using sysrepocfg
Infix supports IETF Hardware YANG with augments for ONIE formatted
production data stored in EEPROMs, if available. See Infix [VPD
documentation][5], as well as *ietf-hardware* and *infix-hardware* YANG
models for details.
```
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d operational -x /ietf-hardware:hardware'
{
"ietf-hardware:hardware": {
"component": [
{
"name": "product",
"class": "infix-hardware:vpd",
"serial-num": "12345",
"model-name": "Switch2010",
"mfg-date": "2024-01-30T16:42:37+00:00",
"infix-hardware:vpd-data": {
"product-name": "Switch2010",
"part-number": "ABC123-001",
"serial-number": "007",
"mac-address": "00:53:00:01:23:45",
"manufacture-date": "01/30/2024 16:42:37",
"num-macs": 11,
"manufacturer": "ACME Production",
"vendor": "SanFran Networks"
}
},
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked",
"oper-state": "enabled"
}
}
]
}
}
~$
```
## Miscellaneous
### <a id="port-test-intro"></a> Port Configuration Example for Production Tests
As part of production tests, verification Ethernet ports are expected
to be performed. A common way is to connect a test PC to two ports and
send a *ping* traversing all ports. This can be achieved by using
VLANs on the switch as described in this section. The resulting
configuration file can be applied to the running configuration of the
produced unit, e.g, use config file restore as described
[above](#restore).
In this example we assume a 10 port switch, with ports e1-e10.
The following VLAN configuration and cable connections will be used:
| VLAN & Ports | Connect |
|:------------------|:----------|
| VLAN 10: e1 & e2 | e2 <=> e3 |
| VLAN 20: e3 & e4 | e4 <=> e5 |
| VLAN 30: e5 & e6 | e6 <=> e7 |
| VLAN 40: e7 & e8 | e8 <=> e9 |
| VLAN 50: e9 & e10 | |
The test PC is connected to e1 and e10 via different interfaces
(alternatively, two different PCs are used).
> Configuration here is done via console. When configuring remotely
> over SSH, remember to keep one IP address (the one used for the SSH
> connection)! I.e., set a static IP address first, then perform the
> VLAN configuration step."
#### Configuration at Start
Starting out, we assume a configuration where all ports are network
interfaces (possibly with IPv6 enabled).
``` shell
admin@example:/> show interfaces
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
e10 ethernet UP 00:53:00:06:11:0a
ipv6 fe80::0053:00ff:fe06:110a/64 (link-layer)
admin@example:/>
```
#### Creating Bridge and Adding Ports
The example below uses Infix documentation on [creating bridges][8].
``` shell
admin@example:/> configure
admin@example:/config/> edit interface br0
admin@example:/config/interface/br0/> end
admin@example:/config/> set interface e1 bridge-port bridge br0
admin@example:/config/> set interface e2 bridge-port bridge br0
admin@example:/config/> set interface e3 bridge-port bridge br0
admin@example:/config/> set interface e4 bridge-port bridge br0
admin@example:/config/> set interface e5 bridge-port bridge br0
admin@example:/config/> set interface e6 bridge-port bridge br0
admin@example:/config/> set interface e7 bridge-port bridge br0
admin@example:/config/> set interface e8 bridge-port bridge br0
admin@example:/config/> set interface e9 bridge-port bridge br0
admin@example:/config/> set interface e10 bridge-port bridge br0
admin@example:/config/>
```
The interface status can be viewed using "show interface" after
leaving configuration context. If configuration via SSH, first assign
an IP address to br0 before *leaving* configuration context, e.g.,
`set interface br0 ipv6 enabled` to get auto-configured IPv6
address. Or skip 'leave' and stay in configuration context until done
with all sections, including the one on [Add IP on
Switch](#ip-on-switch).
``` shell
admin@example:/config/> leave
admin@example:/>
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge LOWER-DOWN
├ e2 bridge LOWER-DOWN
├ e3 bridge LOWER-DOWN
├ e4 bridge LOWER-DOWN
├ e5 bridge LOWER-DOWN
├ e6 bridge LOWER-DOWN
├ e7 bridge LOWER-DOWN
├ e8 bridge LOWER-DOWN
├ e9 bridge LOWER-DOWN
└ e10 bridge FORWARDING
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
```
#### Assign VLANs to Ports
Then configure VLANs as outlined [above](#port-test-intro):
default VID for ingress (PVID), which is done per port, and egress
mode (untagged), which is done at the bridge level. See Infix
[documentation for VLAN bridges][9] for more information.
``` shell
admin@example:/>
admin@example:/> configure
admin@example:/config/> set interface e1 bridge-port pvid 10
admin@example:/config/> set interface e2 bridge-port pvid 10
admin@example:/config/> set interface e3 bridge-port pvid 20
admin@example:/config/> set interface e4 bridge-port pvid 20
admin@example:/config/> set interface e5 bridge-port pvid 30
admin@example:/config/> set interface e6 bridge-port pvid 30
admin@example:/config/> set interface e7 bridge-port pvid 40
admin@example:/config/> set interface e8 bridge-port pvid 40
admin@example:/config/> set interface e9 bridge-port pvid 50
admin@example:/config/> set interface e10 bridge-port pvid 50
admin@example:/config/> edit interface br0
admin@example:/config/interface/br0/> edit bridge vlans
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 untagged e1
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 untagged e2
admin@example:/config/interface/br0/bridge/vlans/> set vlan 20 untagged e3
admin@example:/config/interface/br0/bridge/vlans/> set vlan 20 untagged e4
admin@example:/config/interface/br0/bridge/vlans/> set vlan 30 untagged e5
admin@example:/config/interface/br0/bridge/vlans/> set vlan 30 untagged e6
admin@example:/config/interface/br0/bridge/vlans/> set vlan 40 untagged e7
admin@example:/config/interface/br0/bridge/vlans/> set vlan 40 untagged e8
admin@example:/config/interface/br0/bridge/vlans/> set vlan 50 untagged e9
admin@example:/config/interface/br0/bridge/vlans/> set vlan 50 untagged e10
admin@example:/config/interface/br0/bridge/vlans/> leave
admin@example:/>
```
Interface status would now should something like the following
``` shell
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge LOWER-DOWN vlan:10u pvid:10
├ e2 bridge LOWER-DOWN vlan:10u pvid:10
├ e3 bridge LOWER-DOWN vlan:20u pvid:20
├ e4 bridge LOWER-DOWN vlan:20u pvid:20
├ e5 bridge LOWER-DOWN vlan:30u pvid:30
├ e6 bridge LOWER-DOWN vlan:30u pvid:30
├ e7 bridge LOWER-DOWN vlan:40u pvid:40
├ e8 bridge LOWER-DOWN vlan:40u pvid:40
├ e9 bridge LOWER-DOWN vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
```
#### Connect Cables and Test
We can now connect the PC to e1 and e10, and the other ports are
patched according to plan [above](#port-test-intro). We should get
link up on all ports.
``` shell
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid:10
├ e2 bridge FORWARDING vlan:10u pvid:10
├ e3 bridge FORWARDING vlan:20u pvid:20
├ e4 bridge FORWARDING vlan:20u pvid:20
├ e5 bridge FORWARDING vlan:30u pvid:30
├ e6 bridge FORWARDING vlan:30u pvid:30
├ e7 bridge FORWARDING vlan:40u pvid:40
├ e8 bridge FORWARDING vlan:40u pvid:40
├ e9 bridge FORWARDING vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
```
Here we use IPv6 ping all hosts (ff02::1) on PC interface eth1 to
check reachability to the other interface of the PC.
> A recommendation is to use network name spaces on PC to ensure
> traffic really goes out to switch, instead of being looped
> internally. Or use two PCs.
``` shell
~ $ ping -L ff02::1%eth1
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.496 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.514 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.473 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.736 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=5 ttl=64 time=0.563 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=6 ttl=64 time=0.507 ms
^C
--- ff02::1%eth1 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5108ms
rtt min/avg/max/mdev = 0.473/0.548/0.736/0.088 ms
~ $
```
We can verify that traffic goes through the switch by disconnecting
one of the patch cables, e.g., between e4 and e5
``` shell
~ $ ping -L ff02::1%eth1
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.510 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.448 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.583 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.515 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=5 ttl=64 time=0.521 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=6 ttl=64 time=0.495 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=7 ttl=64 time=0.743 ms
... Disconnecting patch cable, thus losing packets
... and reconnecting again. Connectivity resumes.
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=16 ttl=64 time=0.961 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=17 ttl=64 time=0.513 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=18 ttl=64 time=0.794 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=19 ttl=64 time=0.755 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=20 ttl=64 time=0.779 ms
^C
--- ff02::1%eth1 ping statistics ---
20 packets transmitted, 12 received, 40% packet loss, time 19432ms
rtt min/avg/max/mdev = 0.448/0.634/0.961/0.156 ms
~ $
```
#### <a id="ip-on-switch"></a> Add IP Address on Switch
The configuration so far does not provide a means to connect to the
switch management via SSH or NETCONF, as the switch has no IP
address. The example below shows how to add the switch to VLAN 10 (as
used for ports e1 and e2) and enables IPv6.
``` shell
admin@example:/config/> edit interface vlan10
admin@example:/config/interface/vlan10/> set vlan lower-layer-if br0
admin@example:/config/interface/vlan10/> set ipv6 enabled
admin@example:/config/interface/vlan10/> show
type vlan;
ipv6 {
enabled true;
}
vlan {
tag-type c-vlan;
id 10;
lower-layer-if br0;
}
admin@example:/config/interface/vlan10/>
admin@example:/config/interface/vlan10/> end
admin@example:/config/> edit interface br0 bridge vlans
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 tagged br0
admin@example:/config/interface/br0/bridge/vlans/> leave
admin@example:/>
```
Interface *vlan10* with an auto-configured IPv6 address should appear.
``` shell
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
br0 bridge vlan:10t
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid:10
├ e2 bridge FORWARDING vlan:10u pvid:10
├ e3 bridge FORWARDING vlan:20u pvid:20
├ e4 bridge FORWARDING vlan:20u pvid:20
├ e5 bridge FORWARDING vlan:30u pvid:30
├ e6 bridge FORWARDING vlan:30u pvid:30
├ e7 bridge FORWARDING vlan:40u pvid:40
├ e8 bridge FORWARDING vlan:40u pvid:40
├ e9 bridge FORWARDING vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
vlan10 ethernet UP 00:53:00:06:11:01
│ ipv6 fe80::0053:00ff:fe06:1101/64 (link-layer)
└ br0 ethernet UP 00:53:00:06:11:01
admin@example:/>
```
When pinging "IPv6 all hosts" from the PC, there should be two
responses for every ping, one from the switch and one from the PC
attached to e10.
``` shell
~ $ ping -L ff02::1%eth1
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.508 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=1 ttl=64 time=0.968 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.866 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=2 ttl=64 time=0.867 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=3 ttl=64 time=0.467 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.469 ms
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.452 ms
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=4 ttl=64 time=0.453 ms
^C
--- ff02::1%eth1 ping statistics ---
4 packets transmitted, 4 received, +4 duplicates, 0% packet loss, time 3031ms
rtt min/avg/max/mdev = 0.452/0.631/0.968/0.211 ms
~ $
```
It should now be possible to access the switch from the PC via SSH (or NETCONF).
``` shell
~ $ ssh admin@fe80::0053:00ff:fe06:1101%eth1
admin@fe80::0053:00ff:fe06:1101%eth1's password:
.-------.
| . . | Infix -- a Network Operating System
|-. v .-| https://kernelkit.github.io
'-'---'-'
Run the command 'cli' for interactive OAM
admin@example:~$ exit
~ $
```
See previous sections on [backup](#backup) and [restore](#restore) of
the created configuration.
[1]: discovery.md
[2]: https://rauc.io/
[3]: boot.md#system-upgrade
[4]: https://netopeer.liberouter.org/doc/sysrepo/libyang1/html/sysrepocfg.html
[5]: vpd.md
[6]: https://docs.kernel.org/leds/leds-class.html
[7]: https://docs.kernel.org/power/power_supply_class.html
[8]: networking.md#bridging
[9]: networking.md#vlan-filtering-bridge
+2 -3
View File
@@ -7,14 +7,13 @@ run name:bootstrap log:prio:user.notice norestart <pid/syslogd> \
run name:error :1 log:console norestart if:<run/bootstrap/failure> \
[S] /usr/libexec/confd/error --
service name:confd log <run/bootstrap/success> \
service name:confd log:prio:daemon.err <run/bootstrap/success> \
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -- Configuration daemon
# Bootstrap system with startup-config, ensure correct ownership
# Bootstrap system with startup-config
run name:startup log:prio:user.notice norestart <pid/confd> \
[S] /usr/libexec/confd/load startup-config \
-- Loading startup-config
task [S] <pid/confd> chown admin:wheel /cfg/startup-config.cfg --
# Run if loading startup-config fails for some reason
run name:failure log:prio:user.critical norestart <pid/confd> if:<run/startup/failure> \
+2
View File
@@ -1 +1,3 @@
#set DEBUG=1
service name:statd log [S12345] <pid/confd> statd -f -p /run/statd.pid -n -- Status daemon
@@ -1,7 +1,7 @@
From 49c660c412342e1af76735e75cd3f286ae655b82 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 28 Mar 2023 10:37:53 +0200
Subject: [PATCH 1/4] sysrepo-plugind: add support for running in foreground
Subject: [PATCH 1/5] sysrepo-plugind: add support for running in foreground
with syslog
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 87224ddce4ed1a118b3efb24e0dc7167f8754c22 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 7 Jun 2023 15:19:13 +0200
Subject: [PATCH 2/4] Refactor _sr_install_modules() to use
Subject: [PATCH 2/5] Refactor _sr_install_modules() to use
ly_ctx_load_module()
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 2d3b9524b1448dd6a8ef83e4e101e509d2552dcc Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Fri, 16 Jun 2023 12:13:16 +0200
Subject: [PATCH 3/4] Add support for loading /etc/sysrepo/factory-default
Subject: [PATCH 3/5] Add support for loading /etc/sysrepo/factory-default
Organization: Addiva Elektronik
Follow-up to 3d07270 which adds support for compile-time defaults, this
@@ -1,7 +1,7 @@
From 7726017815243818f07936e4ff3bb979e9291f04 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Fri, 16 Jun 2023 16:17:27 +0200
Subject: [PATCH 4/4] sysrepoctl: add support for -Cfactory -d running
Subject: [PATCH 4/5] sysrepoctl: add support for -Cfactory -d running
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
@@ -0,0 +1,152 @@
From 49b558067ab7c6f59ec84f14cc89201b4a7bde57 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 7 May 2024 15:41:53 +0200
Subject: [PATCH 5/5] Allow SR_EV_DONE to return any error to sysrepocfg
Organization: Addiva Elektronik
Importing a system configuration with sysrepocfg the model callbacks do
their best to validate the configuration and prepare the transaction in
SR_EV_CHANGE. In cases when dealing with a complex system, like adding
a route, address, or other change using iproute2, we may still get into
trouble when actually sending off the transaction in SR_EV_DONE.
If something does go wrong we'd like to know this by the exit code of
sysrepocfg, not by inspecting logs or expected system state.
This patch is a clumsy way of forcing the (first) error to bubble up to
the surface and cause a non-zero exit code from sysrepocfg.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/shm_sub.c | 36 ++++++++++++++++++++++++++++--------
src/shm_sub.h | 2 +-
src/sysrepo.c | 2 +-
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/src/shm_sub.c b/src/shm_sub.c
index 99b2be37..298d7dd3 100644
--- a/src/shm_sub.c
+++ b/src/shm_sub.c
@@ -1586,7 +1586,7 @@ cleanup:
sr_error_info_t *
sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *orig_name, const void *orig_data,
- uint32_t timeout_ms)
+ uint32_t timeout_ms, sr_error_info_t **cb_err_info)
{
sr_error_info_t *err_info = NULL;
struct sr_mod_info_mod_s *mod = NULL;
@@ -1717,12 +1717,19 @@ sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *
sr_rwunlock(&nsub->sub_shm->lock, 0, SR_LOCK_WRITE, cid, __func__);
nsub->lock = SR_LOCK_NONE;
- /* we do not care about an error */
- sr_errinfo_free(&nsub->cb_err_info);
-
SR_LOG_INF("EV ORIGIN: \"%s\" \"%s\" ID %" PRIu32 " priority %" PRIu32 " succeeded.",
nsub->mod->ly_mod->name, sr_ev2str(SR_SUB_EV_DONE), nsub->mod->request_id, nsub->cur_priority);
+ /*
+ * unexpected critical error, merge and cleanup, let
+ * sysrepocfg caller handle undefined system state.
+ */
+ if (nsub->cb_err_info) {
+ sr_errinfo_merge(cb_err_info, nsub->cb_err_info);
+ nsub->cb_err_info = NULL;
+ goto cleanup;
+ }
+
nsub->pending_event = 0;
}
} while (1);
@@ -3167,7 +3174,7 @@ sr_shmsub_change_listen_check_update_edit(sr_session_ctx_t *ev_sess, const char
sr_error_info_t *
sr_shmsub_change_listen_process_module_events(struct modsub_change_s *change_subs, sr_conn_ctx_t *conn)
{
- sr_error_info_t *err_info = NULL;
+ sr_error_info_t *err_info = NULL, *err_tmp;
uint32_t i, data_len = 0, valid_subscr_count;
char *data = NULL, *shm_data_ptr;
int ret = SR_ERR_OK;
@@ -3289,6 +3296,11 @@ process_event:
}
break;
}
+ } else if (sub_info.event == SR_SUB_EV_DONE) {
+ if (ret && err_code == SR_ERR_OK) {
+ /* unexpected, callback actually failed, save for later. */
+ err_code = ret;
+ }
}
/* subscription processed this event */
@@ -3330,6 +3342,11 @@ process_event:
}
break;
case SR_SUB_EV_DONE:
+ if (err_code) {
+ /* prepare unexepected error from session to be written to SHM */
+ sr_errinfo_new(&err_info, err_code, "Oups, error detected in SR_EV_DONE");
+ }
+ break;
case SR_SUB_EV_ABORT:
/* nothing to do */
break;
@@ -3349,14 +3366,17 @@ process_event:
/* SUB WRITE URGE LOCK */
if (sr_shmsub_change_listen_relock(multi_sub_shm, SR_LOCK_WRITE_URGE, &sub_info, change_sub, change_subs->module_name,
- ret, ev_sess, &err_info)) {
+ ret, ev_sess, &err_tmp)) {
+ if (err_tmp)
+ err_info = err_tmp;
goto cleanup;
}
sub_lock = SR_LOCK_WRITE_URGE;
/* finish event */
- if ((err_info = sr_shmsub_multi_listen_write_event(multi_sub_shm, valid_subscr_count, err_code, &shm_data_sub, data,
+ if ((err_tmp = sr_shmsub_multi_listen_write_event(multi_sub_shm, valid_subscr_count, err_code, &shm_data_sub, data,
data_len, change_subs->module_name, err_code ? "fail" : "success"))) {
+ err_info = err_tmp;
goto cleanup;
}
@@ -3886,7 +3906,7 @@ finish_iter:
sr_errinfo_free(&cb_err_info);
/* publish "done" event */
- if ((err_info = sr_shmsub_change_notify_change_done(&mod_info, NULL, NULL, SR_CHANGE_CB_TIMEOUT))) {
+ if ((err_info = sr_shmsub_change_notify_change_done(&mod_info, NULL, NULL, SR_CHANGE_CB_TIMEOUT, &cb_err_info))) {
goto cleanup_unlock;
}
diff --git a/src/shm_sub.h b/src/shm_sub.h
index 3056e4c5..460ad927 100644
--- a/src/shm_sub.h
+++ b/src/shm_sub.h
@@ -144,7 +144,7 @@ sr_error_info_t *sr_shmsub_change_notify_change(struct sr_mod_info_s *mod_info,
* @return err_info, NULL on success.
*/
sr_error_info_t *sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *orig_name,
- const void *orig_data, uint32_t timeout_ms);
+ const void *orig_data, uint32_t timeout_ms, sr_error_info_t **cb_err_info);
/**
* @brief Notify about (generate) a change "abort" event.
diff --git a/src/sysrepo.c b/src/sysrepo.c
index ca2a20b7..e7c1fd0e 100644
--- a/src/sysrepo.c
+++ b/src/sysrepo.c
@@ -3801,7 +3801,7 @@ store:
}
/* publish "done" event, all changes were applied */
- if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms))) {
+ if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms, cb_err_info))) {
goto cleanup;
}
--
2.34.1
+1 -1
View File
@@ -72,7 +72,7 @@ collate()
# Report error on console, syslog, and set login banners for getty + ssh
console_error()
{
logger -p user.crit -t "BOOTSTRAP" "$1"
logger -p user.crit -t bootstrap "$1"
# shellcheck disable=SC3037
/bin/echo -e "\n\n\e[31mCRITICAL BOOTSTRAP ERROR\n$1\e[0m\n" > /dev/console
+34 -4
View File
@@ -19,6 +19,16 @@ banner_append()
return 0
}
note()
{
logger -s -I $$ -p user.notice -t load "$*"
}
err()
{
logger -s -I $$ -p user.error -t load "$*"
}
# shellcheck disable=SC1091
. /etc/confdrc
@@ -35,17 +45,31 @@ else
fi
if [ ! -f "$fn" ]; then
logger -sik -p user.error "No such file, $fn, aborting!"
err "No such file, $fn, aborting!"
exit 1
fi
note "Loading $config ..."
if ! sysrepocfg -v3 -I"$fn" -f json; then
case "$config" in
startup-config)
logger -sik -p user.error "Failed loading $fn, reverting to Fail Secure mode!"
err "Failed loading $fn, reverting to Fail Secure mode!"
# On failure to load startup-config the system is in an undefined state
cat <<-EOF >/tmp/factory.json
{
"infix-factory-default:factory-default": {}
}
EOF
# Default timeout is 2 seconds, allow time to clean up shm
if ! sysrepocfg -f json -t 10 -R /tmp/factory.json; then
rm -f /etc/sysrepo/data/*startup*
rm -f /etc/sysrepo/data/*running*
rm -f /dev/shm/sr_*
killall sysrepo-plugind
fi
;;
failure-config)
logger -sik -p user.error "Failed loading $fn, aborting!"
err "Failed loading $fn, aborting!"
banner_append "CRITICAL ERROR: Logins are disabled, no credentials available"
initctl -nbq runlevel 9
;;
@@ -53,7 +77,13 @@ if ! sysrepocfg -v3 -I"$fn" -f json; then
exit 1
fi
logger -sik -p user.notice "Loaded $fn successfully."
note "Loaded $fn successfully."
if [ "$config" = "failure-config" ]; then
banner_append "ERROR: Corrupt startup-config, system has reverted to default login credentials"
else
# Ensure correct ownership and permissions, in particular after factory reset
# Created by the system, writable by any user in the admin group.
chown root:wheel "$fn"
chmod 0660 "$fn"
fi
+1 -1
View File
@@ -1,3 +1,3 @@
factorydir = $(pkgdatadir)/factory.d
dist_factory_DATA = 10-nacm.json 10-netconf-server.json \
10-infix-system.json 10-system.json
10-infix-services.json 10-system.json
+1 -1
View File
@@ -434,7 +434,7 @@ int cni_ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
return SR_ERR_SYS;
err = sr_get_data(session, path, 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err;
node = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
+1 -1
View File
@@ -196,7 +196,7 @@ static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const cha
return SR_ERR_OK;
rc = sr_get_data(session, XPATH_BASE_ "//.", 0, 0, 0, &cfg);
if (rc)
if (rc || !cfg)
goto err;
rc = srx_get_diff(session, &diff);
+1 -1
View File
@@ -1699,7 +1699,7 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
return err;
err = sr_get_data(session, "/interfaces/interface", 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, (struct lyd_node **)&diff);
+9 -2
View File
@@ -348,6 +348,11 @@ static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t su
}
rc = sr_get_data(session, "/ietf-routing:routing/control-plane-protocols//.", 0, 0, 0, &cfg);
if (rc || !cfg) {
NOTE("No control-plane-protocols available.");
goto err_close;
}
LY_LIST_FOR(lyd_child(cfg->tree), tmp) {
LY_LIST_FOR(lyd_child(tmp), cplane) {
const char *type;
@@ -360,11 +365,13 @@ static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t su
}
}
}
fclose(fp);
sr_release_data(cfg);
err_close:
fclose(fp);
if (!staticd_enabled)
(void)remove(STATICD_CONF_NEXT);
sr_release_data(cfg);
err_abandon:
return rc;
}
+122 -80
View File
@@ -4,6 +4,8 @@
#include <ctype.h>
#include <paths.h>
#include <pwd.h>
#include <grp.h>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
@@ -442,7 +444,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
continue;
name = sr_val_to_str(old);
DEBUG("Removing NTP server %s\n", name);
DEBUG("Removing NTP server %s", name);
erasef("/etc/chrony/sources.d/%s.sources", name);
free(name);
changes++;
@@ -542,12 +544,11 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
case SR_EV_DONE:
/* Check if passed validation in previous event */
if (access(RESOLV_NEXT, F_OK))
return SR_ERR_OK;
(void)remove(RESOLV_PREV);
(void)rename(RESOLV_CONF, RESOLV_PREV);
(void)rename(RESOLV_NEXT, RESOLV_CONF);
if (!access(RESOLV_NEXT, F_OK)) {
(void)remove(RESOLV_PREV);
(void)rename(RESOLV_CONF, RESOLV_PREV);
(void)rename(RESOLV_NEXT, RESOLV_CONF);
}
/* in bootstrap, another resolvconf will soon take your call */
if (systemf("initctl -bq cond get hook/sys/up"))
@@ -594,11 +595,10 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
goto fail;
for (size_t i = 0; i < cnt; i++) {
const char *xpath = val[i].xpath;
char *ptr;
/* Get /ietf-system:system/dns-resolver/server[name='foo'] */
ptr = srx_get_str(session, "%s/udp-and-tcp/address", xpath);
ptr = srx_get_str(session, "%s/udp-and-tcp/address", val[i].xpath);
if (ptr)
/* XXX: add support also for udp-and-tcp/port */
fprintf(fp, "nameserver %s\n", ptr);
@@ -637,7 +637,7 @@ static char *sys_find_usable_shell(sr_session_ctx_t *sess, char *name)
sr_data_t *cfg;
snprintf(xpath, sizeof(xpath), XPATH_AUTH_"/user[name='%s']/infix-system:shell", name);
if (!sr_get_data(sess, xpath, 0, 0, 0, &cfg)) {
if (!sr_get_data(sess, xpath, 0, 0, 0, &cfg) && cfg) {
struct lyd_node *node;
if (!lyd_find_path(cfg->tree, xpath, 0, &node))
@@ -666,41 +666,18 @@ static char *sys_find_usable_shell(sr_session_ctx_t *sess, char *name)
shell = LOGIN_SHELL;
shell = strdup(shell);
sr_release_data(cfg);
if (cfg)
sr_release_data(cfg);
return shell;
}
static uid_t sys_home_exists(char *user)
{
char path[strlen(user) + 10];
struct stat st;
snprintf(path, sizeof(path), "/home/%s", user);
if (stat(path, &st))
return 0;
return st.st_uid;
}
static int sys_uid_busy(char *user, uid_t uid)
{
struct passwd *pw;
int rc = 0;
setpwent();
while ((pw = getpwent())) {
if (pw->pw_uid != uid)
continue;
if (strcmp(pw->pw_name, user))
rc = -1;
}
endpwent();
return rc;
}
static int sys_del_user(char *user)
/*
* Used both when deleting a user from the system configuration, and
* when cleaning up stale users while adding a new user to the system.
* In the latter case we don't need to log failure/success.
*/
static int sys_del_user(char *user, bool silent)
{
char *args[] = {
"deluser", "--remove-home", user, NULL
@@ -710,49 +687,71 @@ static int sys_del_user(char *user)
erasef("/var/run/sshd/%s.keys", user);
err = systemv_silent(args);
if (err) {
ERROR("Error deleting user \"%s\"\n", user);
if (!silent)
ERROR("Error deleting user \"%s\"", user);
/* Ensure $HOME is removed at least. */
systemf("rm -rf /home/%s", user);
return SR_ERR_SYS;
}
NOTE("User \"%s\" deleted\n", user);
if (!silent)
NOTE("User \"%s\" deleted", user);
return SR_ERR_OK;
}
static int sys_add_new_user(sr_session_ctx_t *sess, char *name)
/*
* Helper for sys_add_user(), notice how uid:gid must never be 0:0, it
* is reserved for the system root user which is never created/deleted.
*
* This function balances both /etc/passwd and /etc/group, so to make
* things a little bit easier, we simplify the world and reserve the
* same group name as the username. This means we can always remove
* any stale group entries first.
*
* When uid:gid is non-zero we create the user and re-attach them with
* their $HOME. When uid:gid *is* zero, however, we must make sure to
* clean up any stale user + $HOME before calling adduser to allocate
* a new uid:gid pair for the new user.
*
* If this function fails, it is up to the callee to retry the operation
* with a zero uid:gid pair, which is the most iron clad form.
*/
static int sys_call_adduser(sr_session_ctx_t *sess, char *name, uid_t uid, gid_t gid)
{
char *shell = sys_find_usable_shell(sess, name);
char uid_str[10];
char *eargs[] = {
"adduser", "-d", "-s", shell, "-u", NULL, "-H", name, NULL
"adduser", "-d", "-s", shell, "-u", NULL, "-G", NULL, "-H", name, NULL
};
char *nargs[] = {
"adduser", "-d", "-s", shell, name, NULL
};
bool do_chown = false;
char uid_str[10], grp_str[strlen(name) + 1];
char **args;
uid_t uid;
int err;
uid = sys_home_exists(name);
if (uid) {
if (sys_uid_busy(name, uid)) {
/* Exists but owned by someone else. */
ERROR("Creating user %s, /home/%s existed but was owned by another uid (%d)",
name, name, uid);
ERROR("Cleaning up stale /home/%s", name);
systemf("rm -rf /home/%s", name);
args = nargs;
} else {
/* Not in passwd or owned by us already */
do_chown = true;
DEBUG("Adding new user %s, cleaning up any stale group.", name);
systemf("delgroup %s 2>/dev/null", name);
/* reusing existing uid:gid from $HOME */
if (uid && gid) {
/* recreate group first */
systemf("addgroup -g %d %s", gid, name);
snprintf(uid_str, sizeof(uid_str), "%d", uid);
snprintf(grp_str, sizeof(grp_str), "%s", name);
eargs[5] = uid_str;
eargs[7] = grp_str;
args = eargs;
} else {
DEBUG("Cleaning up any stale user %s and /home/%s", name, name);
sys_del_user(name, true);
NOTE("Reusing uid %d and /home/%s for new user %s", uid, name, name);
snprintf(uid_str, sizeof(uid_str), "%d", uid);
eargs[5] = uid_str;
args = eargs;
}
} else
args = nargs;
}
/**
* The Busybox implementation of 'adduser -d' sets the password
@@ -761,14 +760,51 @@ static int sys_add_new_user(sr_session_ctx_t *sess, char *name)
*/
err = systemv_silent(args);
free(shell);
return err;
}
/*
* Create a new (locked) user, if they have a matching $HOME we use the
* uid:gid from that, if they are free. In all cases of conflict with
* any (type of) user we remove the existing $HOME and start with a new
* uid:gid pair.
*/
static int sys_add_user(sr_session_ctx_t *sess, char *name)
{
char home[strlen(name) + 10];
bool reused = false;
struct stat st;
int err;
/* Map users to their existing $HOME */
snprintf(home, sizeof(home), "/home/%s", name);
if (!stat(home, &st)) {
/* Verify IDs aren't already used, like BusyBox adduser */
if (getpwuid(st.st_uid) || getgrgid(st.st_uid) || getgrgid(st.st_gid)) {
/* Exists but owned by someone else. */
ERROR("Failed mapping user %s to /home/%s, uid:gid (%d:%d) already exists.",
name, name, st.st_uid, st.st_gid);
err = sys_call_adduser(sess, name, 0, 0);
} else {
DEBUG("Reusing uid:gid %d:%d and /home/%s for new user %s",
st.st_uid, st.st_gid, name, name);
err = sys_call_adduser(sess, name, st.st_uid, st.st_gid);
if (err) {
ERROR("Failed reusing uid:gid from /home/%s, retrying create user ...", name);
err = sys_call_adduser(sess, name, 0, 0);
} else
reused = true;
}
} else
err = sys_call_adduser(sess, name, 0, 0);
if (err) {
ERROR("Failed creating new user \"%s\"\n", name);
ERROR("Failed creating new user \"%s\"", name);
return SR_ERR_SYS;
}
NOTE("New user \"%s\" created\n", name);
if (do_chown)
systemf("chown -R %s:%s /home/%s", name, name, name);
NOTE("User \"%s\" created%s.", name, reused ? ", mapped to existing home directory" : "");
/*
* OpenSSH in Infix has been set up to use /var/run/sshd/%s.keys
@@ -776,6 +812,7 @@ static int sys_add_new_user(sr_session_ctx_t *sess, char *name)
* /home/%s/.ssh/authorized_keys file. This creates a both the
* directory and the symlink owned by root to prevent tampering.
*/
DEBUG("Adding secure /home/%s/.ssh directory.", name);
fmkpath(0750, "/home/%s/.ssh", name);
systemf("ln -sf /var/run/sshd/%s.keys /home/%s/.ssh/authorized_keys", name, name);
@@ -803,7 +840,7 @@ static char *change_get_user(struct sr_change *change)
if (user) {
pw = getpwnam(user);
if (!pw) {
ERROR("Skipping attribute for missing user (%s)", user);
/* Skipping, user probably deleted. */
free(user);
user = NULL;
}
@@ -828,7 +865,7 @@ static sr_error_t handle_sr_passwd_update(augeas *aug, sr_session_ctx_t *, struc
assert(change->new);
if (change->new->type != SR_STRING_T) {
ERROR("Internal error, expected pass to be string type\n");
ERROR("Internal error, expected pass to be string type.");
err = SR_ERR_INTERNAL;
break;
}
@@ -841,7 +878,7 @@ static sr_error_t handle_sr_passwd_update(augeas *aug, sr_session_ctx_t *, struc
* it as "*", meaning the user can log in with SSH keys.
*/
if (!hash || !strlen(hash)) {
ERROR("Empty passwords are not allowed, disabling password login.\n");
ERROR("Empty passwords are not allowed, disabling password login.");
hash = "*";
}
if (aug_set_dynpath(aug, hash, "etc/shadow/%s/password", user))
@@ -882,6 +919,9 @@ static sr_error_t handle_sr_shell_update(augeas *aug, sr_session_ctx_t *sess, st
char *user;
int err;
if (change->op == SR_OP_DELETED)
return SR_ERR_OK;
user = change_get_user(change);
if (!user)
return SR_ERR_OK;
@@ -930,7 +970,7 @@ static sr_error_t handle_sr_user_update(augeas *aug, sr_session_ctx_t *sess, str
assert(change->new);
name = sr_xpath_key_value(change->new->xpath, "user", "name", &state);
err = sys_add_new_user(sess, name);
err = sys_add_user(sess, name);
if (err) {
sr_xpath_recover(&state);
return err;
@@ -941,7 +981,7 @@ static sr_error_t handle_sr_user_update(augeas *aug, sr_session_ctx_t *sess, str
assert(change->old);
name = sr_xpath_key_value(change->old->xpath, "user", "name", &state);
err = sys_del_user(name);
err = sys_del_user(name, false);
if (err) {
sr_xpath_recover(&state);
return err;
@@ -973,8 +1013,9 @@ static sr_error_t generate_auth_keys(sr_session_ctx_t *session, const char *xpat
sr_error_t err = 0;
sr_data_t *cfg;
/* err may be OK and cfg NULL if 'no system' */
err = sr_get_data(session, xpath, 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
return err;
auth = lydx_get_descendant(cfg->tree, "system", "authentication", NULL);
@@ -1043,7 +1084,7 @@ static sr_error_t change_auth_done(augeas *aug, sr_session_ctx_t *session)
*/
err = aug_load(aug);
if (err) {
ERROR("Error loading files into aug tree\n");
ERROR("Error loading files into aug tree.");
return SR_ERR_INTERNAL;
}
@@ -1079,7 +1120,7 @@ static sr_error_t change_auth_done(augeas *aug, sr_session_ctx_t *session)
return err;
}
DEBUG("Changes to authentication saved\n");
DEBUG("Changes to authentication saved.");
return SR_ERR_OK;
}
@@ -1326,8 +1367,9 @@ static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const cha
nm = srx_get_str(session, "%s", xpath);
if (!nm) {
/* XXX: derive from global "options.h" or /usr/share/factory/ */
nm = strdup("infix");
nm = fgetkey("/etc/os-release", "DEFAULT_HOSTNAME");
if (nm)
nm = strdup(nm);
if (!nm) {
err = SR_ERR_NO_MEMORY;
goto err;
+1 -1
View File
@@ -226,7 +226,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
}
err = sr_get_data(session, CFG_XPATH "//.", 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, &diff);
+1 -1
View File
@@ -278,7 +278,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
}
err = sr_get_data(session, XPATH "//.", 0, 0, 0, &cfg);
if (err)
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, &diff);
+1 -1
View File
@@ -104,7 +104,7 @@ static sr_data_t *get(sr_session_ctx_t *session, sr_event_t event, const char *x
return NULL; /* Don't care about CHANGE, ABORT, etc. */
snprintf(path, sizeof(path), "%s//.", xpath);
if (sr_get_data(session, path, 0, 0, 0, &cfg)) {
if (sr_get_data(session, path, 0, 0, 0, &cfg) || !cfg) {
ERROR("no data for %s", path);
return NULL;
}
+4 -3
View File
@@ -20,12 +20,13 @@ int asprintf(char **strp, const char *fmt, ...);
/*
* Only NOTICE and above are logged by default, see setlogmask() for details.
* Use `set DEBUG=1` at top of package/confd/confd.conf for logmask = debug
*/
#define DEBUG(fmt, ...) do { if (debug) syslog(LOG_DEBUG, fmt, ##__VA_ARGS__); } while (0)
#define INFO(fmt, ...) syslog(LOG_INFO, fmt, ##__VA_ARGS__)
#define NOTE(fmt, ...) syslog(LOG_NOTICE, fmt, ##__VA_ARGS__)
#define WARN(fmt, ...) syslog(LOG_WARNING, "%s: " fmt, __func__, ##__VA_ARGS__)
#define ERROR(fmt, ...) syslog(LOG_ERR, "%s: " fmt, __func__, ##__VA_ARGS__)
#define ERRNO(fmt, ...) syslog(LOG_ERR, "%s: " fmt ": %s", __func__, ##__VA_ARGS__, strerror(errno))
#define WARN(fmt, ...) syslog(LOG_WARNING, fmt, ##__VA_ARGS__)
#define ERROR(fmt, ...) syslog(LOG_ERR, fmt, ##__VA_ARGS__)
#define ERRNO(fmt, ...) syslog(LOG_ERR, fmt ": %s", ##__VA_ARGS__, strerror(errno))
#endif /* CONFD_COMMON_H_ */
+3 -1
View File
@@ -526,9 +526,11 @@ int main(int argc, char *argv[])
struct statd statd = {};
int log_opts = LOG_USER;
sr_conn_ctx_t *sr_conn;
char *env;
int err;
if (argc > 1 && !strcmp(argv[1], "-d")) {
env = getenv("DEBUG");
if (env || (argc > 1 && !strcmp(argv[1], "-d"))) {
log_opts |= LOG_PERROR;
debug = 1;
}