Hot to initialize LTE module using libqmi and systemd-network (networkd-dispatcher) - yocto

I want to initialize the lte module using libqmi and networkd-dispatcher. What I got so far is a shell script which is located at /etc/networkd-dispatcher/degraded.d/01-wwan.sh
#!/bin/bash
interface="${IFACE}"
if [[ "$interface" == *"wwan"* ]]; then
device="/dev/cdc-wdm${interface: -1}"
is_wwan="y"
fi
if [[ "$is_wwan" == "y" ]]; then
ip link set dev "${interface}" down
echo "Y" > "/sys/class/net/${interface}/qmi/raw_ip"
qmi-network "${device}" start || true
qmicli -p -d "${device}" --wds-set-autoconnect-settings=enabled || true
ip link set dev "${interface}" up
fi
My problem now is that this script is called over and over again sometimes after an reboot and takes some time to be stable. I thought if I add a sleep 10s after taking it link up it solves the issue, but it doesn't. Any suggestions how to fix this?

Sorry it's a bit late but just came across this question.
If just for the sake of completeness, a method that I found to be quite predictable and reliable is to link a systemd service file that starts a script with a udev rule:
Create a file in /etc/udev/rules.d, for example 10-lte-modem.rules, which should look like this:
SUBSYSTEM=="net",ACTION=="add",ENV{PRODUCT}=="PID-of-modem", TAG+="systemd",ENV{SYSTEMD_WANTS}
Note you can use different triggers, for example if your modem is at a fixed port on a usb hub then you can use KERNELS="1-1.1". The point is to trigger the systemd service on the enumeration of the modem (which allows you to reboot the modem and your script will automatically re-run). You also might have to add in a NAME= field to give your interface a deterministic name.
In your systemd service file that will start your script, you have something like:
[Unit]
ConditionPathExists=|!/sys/class/net/wwan1
ConditionPathExists=|!/sys/class/net/wwan2
[Service]
Type=simple
Restart=always
RemainAfterExit=no
ExecStart=/bin/sh /etc/networkd-dispatcher/degraded.d/01-wwan.sh
The |! syntax in systemd allows you to OR different conditions.
Depending on the exact setup of your system, like whether its a PCIe modem or USB, you might have to play around with the udev and systemd settings to get what you want, but I've found it results in very stable behaviour.

Related

Install snap() on wsl2 for flutter [duplicate]

I am attempting to debug some C# / .NET 5 code in WSL 2 with Ubuntu on Windows. I have WSL 2 setup with Windows 10 and want to test out creating a Systemd service. Unfortunately, it appears Systemd is not enabled with WSL 2 by default, even though a standard Ubuntu install does have it enabled by default. Is there any way to get Systemd enabled in WSL 2?
Note: See footnote at bottom of this answer for background on this Community Wiki.
There are several possible paths to enabling Systemd on WSL2 (but not WSL1). These are summarized here, with more detail provided below.
Option 1: Upgrade WSL to the latest application release (if supported by your system) and opt-in to the Systemd feature
Option 2: Run a Systemd-helper script designed for WSL2
Option 3: Manually run Systemd in its own namespace
And while not part of this question, for those simply looking to run certain applications that require Systemd, there are alternatives:
On WSL1 and WSL2:
Alternative 1: SysVInit scripts (e.g. sudo service <service_name> start) where available
Alternative 2: Manually configuring and running the service
On WSL2-only:
Alternative 3: Docker
Should you enable Systemd in WSL?
First, consider whether you should or need to enable Systemd in WSL. Enabling Systemd will automatically start a number of background services and tasks that you really may not need under WSL. As a result, it will also increase WSL startup times, although the impact will be dependent on your system. Check the Alternatives section below to see if there may be a better option that fits your needs. For example, the service command may do what you need without any additional effort.
More detail on each answer:
Option 1: Upgrade WSL to the latest application release (if supported by your system) and opt-in to the Systemd feature
Microsoft has now integrated Systemd support in the WSL2 application release (as opposed to the older "Windows feature" implementation).
Starting with WSL Application Release 1.0.0, this feature is available on both Windows 10 and Windows 11. Windows 10 users do need to be on UBR (update build revision) 2311 or later. The UBR is the last 4 digits of your full Windows build number (e.g. 10.0.19045.2311 for Windows 10 22H2). 2311 is installed with KB5020030, an optional Preview update, although if you are reading this later, it will likely be a later (non-Preview) monthly servicing update.
If you are on a supported Windows release, the WSL application with Systemd support can be installed:
Through the Microsoft Store (as "Windows Subsystem for Linux").
Or from the Releases page in the Github repo. To install a release manually:
Reboot (to make sure that WSL is not in use at all). A simple wsl --shutdown may work, but often will not.
Download the 1.0.0 (or later) release from the link above.
Start an Administrator PowerShell and:
Add-AppxPackage <path.to>/Microsoft.WSL_1.0.0.0_x64_ARM64.msixbundle
wsl --version # to confirm
To enable, start your Ubuntu (or other Systemd) distribution under WSL (typically just wsl ~ will work).
sudo -e /etc/wsl.conf
Add the following:
[boot]
systemd=true
Exit Ubuntu and again:
wsl --shutdown
Then restart Ubuntu.
sudo systemctl status
... should show your Systemd services.
Option 2: Run a Systemd-helper script designed for WSL2
There are a number of Systemd-enablement scripts available from various sources. Given the complexities involved in running Systemd under WSL, it is recommended that you:
Use one that is actively maintained
Attempt to understand, as much as possible, how they operate, and how they may impact other features and applications in your distribution(s) under WSL
When asking questions here or on any other site, disclose in the question which script you are using so that others can attempt to understand and/or reproduce your issue in the proper context
Several of the more popular projects that enable Systemd under WSL2 are:
Genie: 1.8k stars, last commit September, 2022
Distrod: 1.4k stars, last commit July 2022
WSL2-Hacks: 1.1k stars, mostly instructional, with a supporting script example. Last commit January, 2022
At the core, all of them operate on the same principles covered in the next option ...
Option 3: Manually run Systemd in its own namespace
One of the main issues with running Systemd in earlier versions of WSL is that both inits need to be PID 1. To get around this, it is possible to create a new namespace or container where Systemd can run as PID 1.
To see how this is done (at a very basic level):
Run:
sudo -b unshare --pid --fork --mount-proc /lib/systemd/systemd --system-unit=basic.target
This starts Systemd in a new namespace with its own PID mapping. Inside that namespace, Systemd will be PID1 (as it must, to function) and own all other processes. However, the "real" PID mapping still exists outside that namespace.
Note that this is a "bare minimum" command-line for starting Systemd. It will not have support for, at least:
Windows Interop (the ability to run Windows .exe)
The Windows PATH (which isn't necessary without Windows Interop anyway)
WSLg
The scripts and projects listed above do extra work to get these things working as well.
Wait a few seconds for Systemd to start up, then:
sudo -E nsenter --all -t $(pgrep -xo systemd) runuser -P -l $USER -c "exec $SHELL"
This enters the namespace, and you can now use ps -efH to see that systemd is running as PID 1 in that namespace.
At this point, you should be able to run systemctl.
And after proving to yourself that it's possible, it is recommended that you exit all WSL instances completely, then doing wsl --shutdown. Otherwise, some things will be "broken" until you do. They can likely be "fixed", but that's beyond the scope this answer. If you are interested, please refer to the projects listed above to see how they handle these situations.
Alternative 1: SysVInit scripts (e.g. sudo service <service_name> start) where available
In Ubuntu, Debian, and some other distributions on WSL, many of the common system services still have the "old" init.d scripts available to be used in place of systemctl with Systemd units. You can see these by using ls /etc/init.d/.
So, for example, you can start ssh with sudo service ssh start, and it will run the /etc/init.d/ssh script with the start argument.
Even some non-default packages such as MySql/MariaDB will install both the Systemd unit files and the old init.d scripts, so you can still use the service command for them as well.
On the hand, some packages, like Elasticsearch, only install Systemd units. And some distributions only provide Systemd units for most (if not all) packages in their repositories.
Alternative 2: Manually configuring and running the service
For those services that don't have a init-script equivalent, it can be possible to run them "manually".
For simplicity, let's assume that the ssh init.d script wasn't available.
In this case, the "answer" is to figure out what the Systemd unit files are doing and attempt to replicate that manually. This can vary widely in complexity. But I'd start with looking at the Systemd unit file that you are trying to run:
less /lib/systemd/system/ssh.service
# Trimmed
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
Some of the less relevant lines have been trimmed to make it easier to parse, but you can man systemd.exec, man systemd.service, and others to see what most of the options do.
In this case, when you sudo systemctl start ssh, it:
Reads environment variables (the $SSHD_OPTS) from /etc/default/ssh
Tests the config, exits if there is a failure
Makes sure the RuntimeDirectory exists with the specified permissions. This translates to /run/sshd (from man systemd.exec). This also removes the runtime directory when you stop the service.
Runs /usr/sbin/sshd with options
So, if you don't have any environment-based config, you could just set up a script to:
Make sure the runtime directory exists. Note that, since it is in /run, which is a tmpfs mount, it will be deleted after every restart of the WSL instance.
Set the permissions to 0755
Start /usr/sbin/sshd as root
... And you would have done the same thing manually without Systemd.
Again, this is probably the simplest example. You might have much more to work through for more complex tasks.
Alternative 3: Docker
Many packages/services are available as Docker images. Docker typically runs very well under Ubuntu on WSL2 (specifically WSL2; it will not run on WSL1). If there's not a SysVinit "service" script for the service you are trying to start, there may very well be a Docker image available that runs in a containerized environment.
Example: Elasticsearch, as in this question.
Bonus #1: Doesn't interfere with other packages already installed (no dependency issues).
Bonus #2: The Docker images themselves pretty much never use Systemd, so you can often inspect the Dockerfile to see how the service is started without Systemd. For more information see the next option - "The manual way."
Microsoft recommends Docker Desktop for Windows for running Docker containers under WSL2.
Footnote This answer is being posted as a Community Wiki because it can apply to multiple Stack Overflow questions. It is originally based on answers to this Ask Ubuntu question. However, it is hoped that this wiki-answer can be continuously updated by the community as Systemd evolves on WSL.
This question has been chosen since:
It appears to be the most canonical, straightforward, "How do I enable Systemd on WSL?" question.
It is on-topic, as *creating Systemd services is (or at least can-be) unique to programming.

How to configure telnet service for yocto image

telnet is necessary in order to maintain compatibility with older software in this case. I'm working with the Yocto Rocko 2.4.2 distribution. when I try to telnet to the board I'm getting the oh so detailed message "connection refused".
Using the method here and the options here I modified the busybox configuration per suggestion. When the board is booted up and logged in, if you execute: telnet, it spits out usage info and a quick directory check shows that telnet is installed to /usr/bin/telnet. My guess is that the telnet client is installed but the telnet server is not running?
I need to get telnetd to start manually at least so I know it will work with an init script in place. The second reference link there suggests that 'telnetd will not be started automatically though...' and that there will need to be an init script. How can I start telnetd manually for testing?
systemctl enable telnetd
returns: Unit telnetd.service could not be found
UPDATE
telnetd in located in /usr/sbin/telnetd. I was able to manually start the telnetd service for testing from there. After manually starting the service telnet login now works. looking into writing a systemd init script to auto start the telnetd service, so I suppose this issue is closed. unless anyone would like to offer up detailed telnet busybox configuration and setup steps as an answer to 'How to configure telnet service for yocto image'
update
Perhaps there is something more? I created a unit file that looks like this:
[Unit]
Description=auto start telnetd
[Service]
ExecStart=/usr/sbin/telnetd
[Install]
WantedBy=multi-user.target
on reboot, systemd indicates the process executed and succeeded:
systemctl status telnetd
.
.
.
Process: 466 ExecStart=/usr/sbin/telnetd (code=exited, status=0/SUCCESS)
.
.
.
The service is not running however. netstat -l does not list it and telnet login fails. Something I'm missing?
last update...i think
so following this post, I managed to get telnet.socket service to startup on reboot.
systemctl status telnet.socket
shows that it is running and listening on 23. Now however, when I try to remote in with telnet I'm getting
Connection closed by foreign host
Everything I've read so far has been talking about xinetd service (which I do not have...). What is confusing is that, if I just navigate to /usr/sbin/ and execute telnetd, the server is up and running and I can telnet into the board, so I do not believe I'm missing any utilities or services (like the above mentioned xinetd), but something is still not being configured correctly. any ideas?

How to troubleshoot services in Rapsberry Pi 3B

I have never done a service before in linux perse, but I been trying to make a service using a Pi.
I used 2 different approaches to create a service. The first approach was using the systemctl using as base the code posted near the end of https://ubuntuforums.org/showthread.php?t=2318279. In my case the ExecStart looks like follow:
ExecStart=/home/pi/berryconda2/bin/python /home/pi/Documents/MyCode.py
When I start this service using sudo systemctl start MyCode.service it appears as active and running until I execute a another that live in my PC and not in the Pi (they communicate with each other), then I get
(code=exited, status=2)
Unit entered failed state.
Failed with result 'exit-code'.
If I run MyCode.py using my default python interpreter my code work, but I want the pi to run the since boot and continue to run it until I turn it off.
Now for my second approach I utilize the steps describe here http://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/. At the end when I run my .sh, I get
active (exited)
(code=exited,status=0/SUCCESS).
As describe in the later link, I run start-stop-daemon --start --pidfile /var/run/MyCode_service.pid --make-pidfile --user root --startas /home/pi/Documents/MyCode.py -- --log /var/log/MyCode_service.log and it work. I'm not sure how to properly debug this services. I have look at https://freedesktop.org/software/systemd/man/systemd.exec.html#id-1.20.8 and http://manpages.ubuntu.com/manpages/cosmic/en/man8/start-stop-daemon.8.html. But I quiet haven't figure it out yet. Can someone point me in the right direction or know of any other building blocks for making a service? or at least trouble shoot it?

How to run Google Assistant library (on AIY kit), upon startup of Raspberry Pi?

We set up a voice kit using Raspberry Pi (using "the MagPi essentials AIY Projects" manual). We are able to enable Google Assistant using the command "src/assistant_library_demo.py" in the dev terminal, after Raspberry Pi starts up. We would like to embed the voice kit in a stuffed animal with a portable power supply (i.e., used to charge cell phone on the go). But when the portable power supply is charged, the Raspberry Pi resets. That requires us to go back into the Raspberry Pi, open the dev terminal, and run the Google Assistant file.
My question: Is it possible to run a startup script that automatically runs Google Assistant upon Raspberry Pi starting up? How to do this?
I ended up creating a crontab job after a 10 second wait. Starting right at boot didn't give it enough time for the internet to connect fully.
In terminal type:
crontab -e
Choose an option if it asks how you want to open/edit the file. Then at the bottom put:
#reboot sleep 10 && /home/pi/pathtofile > /home/pi/cronlog 2>&1
Save the file and reboot or pull the cable out and plug it back in. The cronlog helped me troubleshoot this whole process and get feedback on why it didn't work.
Take a look at this page. It tells you how to set up a service which will run automatically.
If the link has gone bad, here is a short explanation of it:
Create a file called my_assistant.service in the src directory, and put in the following code
[Unit]
Description=My awesome assistant app
[Service]
Environment=XDG_RUNTIME_DIR=/run/user/1000
ExecStart=/bin/bash -c 'python3 -u src/my_assistant.py'
WorkingDirectory=/home/pi/AIY-projects-python
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
Where the file says src/my_assistant.py, replace my_assistant with your program's filename. Now go to the folder that file the .sevice file is in, and run the command sudo mv my_assistant.service /lib/systemd/system/. This code moves the file to the services folder. Now you can run the following commands to change the service:
Enable the service- sudo systemctl enable my_assistant.service
Disable it- sudo systemctl disable my_assistant.service
Start it (just runs it once, enabling makes it run on startup)- sudo service my_assistant start
Stop it- sudo service my_assistant stop
See the logs, when the program was started and if an error occurred- sudo service my_assistant status

Why doesn't my systemd startup script run?

I'm trying to run a trivial script at bootup on my debian testing machine. I followed a few guides, but the services do not start. Can someone show me what I'm doing wrong? I'd like to understand systemd before I start whining about it on the internet.
I created /etc/systemd/system/startup-scripts.service (sometimes here, sometimes as a symlinks to /lib/systemd/system/my-file.service) and wrote
[Unit]
Description=Sync date at boot up
[Service]
ExecStart=/usr/bin/startup-script.sh
Type=simple
[Install]
WantedBy=multi-user.target
then ran
sudo systemctl enable startup-scripts.service
I also filed out /usr/bin/startup-script.sh, made it executable, and ran it. As far as I could tell the script would run, but my reboots have been fruitless.
I'm guessing the answer will involve journalctl. Not really sure what I'm looking at here. I also wouldn't be surprised if multi-user is the wrong target. It was the most reasonable looking one, but I'm not really confident about what it's for.