Łukasz Posted June 7, 2022 Report Share Posted June 7, 2022 Hi, my challenge is to run our LabVIEW application as a Linux service. To achieve that, the systemd file needs to be created which defines execution files for starting and stopping the service. I have already look over the web to find some clues about this topic, however some knowledge is still missing and its related to how LabVIEW build shared library can interact with system. To explain it clearly I present what I have already done. Most services are running without a user interface, so the first task was to create a start execution file (Linux exe). I used this guide (https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019RYlSAM&l=pl-PL) to build our application as a shared library (so no user interface is used) and simple c program to launch it. It works, the application can be run from command line without UI. Similar command can be used in systemd file to define start of service ExecStart=/home/user/Desktop/MyAppNoUI-build/myappstart It also works. The service can be started and stopped. However, the stop function wasn’t defined so Linux sent KillSignal and the application was killed. I think it's not safe, I don't know what happened with all those open references etc. but I’m sure that I don't have any log from the application. So the first question is how to send the signal/message to the LabVIEW app? There is a possibility to specify the execution file which will be triggered on service stop, so this can be used. I have found - very simple - idea to trigger a c program which will create an empty file named “close” in the LabVIEW app directory. LabVIEW app checks periodically the directory and will trigger shutdown case when “close” would be found. This is a working solution, but I’m not sure if it's the best one. Next question is related to servicectl log access. It's very easy to use it in C (all printf functions are redirected to that log when the app is run as a service). However I don't know if it’s possible to do it with the LabVIEW app. I wonder if someone already done similar case so he can share ideas with us. Quote Link to comment
dadreamer Posted June 7, 2022 Report Share Posted June 7, 2022 11 minutes ago, Łukasz said: It also works. The service can be started and stopped. However, the stop function wasn’t defined so Linux sent KillSignal and the application was killed. I think it's not safe, I don't know what happened with all those open references etc. but I’m sure that I don't have any log from the application. So the first question is how to send the signal/message to the LabVIEW app? There is a possibility to specify the execution file which will be triggered on service stop, so this can be used. From my very limited experiments with a common app (not a service), the OS kills it no matter what, leaving no chance to do even some basic cleanup. You may browse through this idea and comments: Notification in Event Structure When Linux is Shuting down Sadly all the attachments there are long gone and I didn't succeed in finding their copies. But even if you would implement that workaround in your application, I highly doubt it would allow to interrupt the shutdown process to do some work in the application as it's provided by modern Windows or Mac OS. 1 Quote Link to comment
JamesMc86 Posted June 7, 2022 Report Share Posted June 7, 2022 I've done something similar before but don't have all the answers. As you described I wrapped the LabVIEW code in a basic C function. The LabVIEW code was compiled to a DLL with the "Use embedded version of run-time engine" option selected. This removes the need for a UI. For shutdown I don't think I did anything special. I was perhaps less concerned as it was an embedded application - I do have a panel close? handler in the code but I can't remember if that fired when it was embedded. Error out is actually pretty simple. You can use the pipes API and write to id 1 for stdout or id 2 for stderr. Below is a screenshot from my error message handler. 1 Quote Link to comment
Łukasz Posted July 4, 2022 Author Report Share Posted July 4, 2022 Thank you James, sending logs to Linux journal is easy thanks to pipes. Since I have not found any way to get any of Linux signal in my application I decided to open named pipe (Linux fifo) and read from it. Simple C application writes to the same pipe when service needs to be stopped. That makes possible to shutdown all LabVIEW modules correctly. Quote Link to comment
Rolf Kalbermatter Posted July 6, 2022 Report Share Posted July 6, 2022 (edited) I haven't tried it but in your minimal C wrapper you should be able to install a SIGTERM handler in this way and in there you could call a second export in the shared library to inform your LabVIEW program that it needs to shut down now! #include <signal.h> #include "SharedLib.h" void handler(int signum) { SharedLibSignal(signum == SIGTERM); } int main() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = handler; if (sigaction(SIGTERM, &action, NULL) == -1) { perror("sigaction"); exit(EXIT_FAILURE); } return SharedLibEntryPoint(); } Edited July 6, 2022 by Rolf Kalbermatter 1 Quote Link to comment
Łukasz Posted July 9, 2022 Author Report Share Posted July 9, 2022 This is a nice improvement. Instead of configuring an additional c app in systemd file, its content can be run in the handler. The minimal wrapper code can be even more straightforward: void handler(int signum) { int fd; char * myfifo = "/tmp/LabVIEWCrossCommunication"; fd = open(myfifo,O_WRONLY); if(fd==-1) { printf("Error opening file: %s\n", strerror(errno)); } else { printf("Sending Close cmd to LabVIEWCrossCommunication \n"); write(fd, "Close", sizeof("Close")); close(fd); } unlink(myfifo); sleep(2); printf("Done\n"); } int main() { // printf("PID : %d\n", getpid()); //test with: kill -s SIGTERM pid signal(SIGTERM, handler); SharedLibEntryPoint(); return 0; } Thank you for your suggestion. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.