Bug 218266 - Need article about Linux shutdown process
Summary: Need article about Linux shutdown process
Status: NEW
Alias: None
Product: Documentation
Classification: Unclassified
Component: man-pages (show other bugs)
Hardware: All Linux
: P3 normal
Assignee: documentation_man-pages@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-12-15 06:29 UTC by Alexander
Modified: 2023-12-25 10:19 UTC (History)
1 user (show)

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Alexander 2023-12-15 06:29:51 UTC
Hi,

I try make correct shutdown (reboot/poweroff) process for applications, but not find info about it.

There are several opinions about this but none of them are confirmed.

1. You need to process the SIGTERM signal. But no one has been able to do this successfully in the context of system shutdown. This is a very common belief or misconception. For example: https://bugzilla.mozilla.org/show_bug.cgi?id=1837907

2. There is no need to save the data at all - let me get lost. But the system will turn off faster. http://freepascal.ru/forum/viewtopic.php?f=1&t=43642

These two directions lead to data loss.

3. It is necessary to process the signal from systemd PrepareForShutdown using dbus. This is a cleaner approach, but more complex and higher level than the kernel signal. In addition, the program must support dbus, and this may seem cumbersome.

Some programming languages (the finalization section in Pasal) contain a system shutdown handler in rtl, while for others this must be separately in each program.

We need a detailed article (apparently not only in man, but also on the web), describing in detail for programs and programming languages (at least C and Pascal) the situation of shutting down the system with working examples. Otherwise, there is serious confusion, leading to disputes among programmers and, ultimately, to data loss.

Thank You.
Comment 1 Alejandro Colomar 2023-12-15 10:27:29 UTC
Hi,

> We need a detailed article (apparently not only in man, but also on the web),
> describing in detail for programs and programming languages (at least C and
> Pascal) the situation of shutting down the system with working examples.
> Otherwise, there is serious confusion, leading to disputes among programmers
> and, ultimately, to data loss.

Would you mind starting to write it?  Maybe a shutdown(7) page would be
appropriate for such an article.

Have a lovely day,
Alex
Comment 2 Alexander 2023-12-15 11:24:41 UTC
> Maybe a shutdown(7) page would be
appropriate for such an article.

No, this is too complex a topic and the current manpages content is clearly not enough. This is not about using the shutdown command, but about the information necessary to build an rtl programming language. Perhaps some explanatory graphical files are also needed.

It is possible, of course, to dramatically simplify the task by making your own patch for the kernel and describing it, but I think it would be better to describe how it works now on the part of the kernel developers. I have nothing to write about now - there is not enough information about the topic.
Comment 3 Alejandro Colomar 2023-12-15 11:34:06 UTC
On Fri, Dec 15, 2023 at 11:24:41AM +0000, bugzilla-daemon@kernel.org wrote:
> No, this is too complex a topic and the current manpages content is clearly
> not
> enough. This is not about using the shutdown command, but about the
> information
> necessary to build an rtl programming language. Perhaps some explanatory
> graphical files are also needed.

I meant in section 7, because that's the Miscellaneous Information
Manual.

The page for the command is shutdown(1).

In section 7 there are some pages that have that style of articles
explaining how to do something.  See for example the most recent
addition: string_copying(7).

> 
> It is possible, of course, to dramatically simplify the task by making your
> own
> patch for the kernel and describing it, but I think it would be better to
> describe how it works now on the part of the kernel developers. I have
> nothing
> to write about now - there is not enough information about the topic.

Ok.

Have a lovely day,
Alex
Comment 4 Rajesh 2023-12-22 14:09:17 UTC
Hello,

When graceful power,shutdown,reboot are done then the process are sent SIGTERM and kernel gives them time to flush or finish their exit gracefully. Then it is followed by SIGKILL which is a sure kill.

I made a test with the following C code. 

After compiling, I tested with poweroff, shutdown, reboot and even send a kill PID and all of them logs with SIGNAL 15 which is the SIGTERM. 

As you can also notice, I have handled to flush the remaining bytes to the disk and then close the file and followed by exit(0). 

Infact systemd does the same thing (Ref : https://github.com/systemd/systemd/blob/main/src/shutdown/shutdown.c ) 

Note: This is a test code and it's log file can grow quiet large. So should not be used in production.


/* Sample test code for handling SIGTERM for graceful shutdown, poweroff, reboot or kill */

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

FILE *fp;

void signalHandler(int signal) {
  if ( signal == SIGTERM) {
     fprintf(fp, "Received signal is: %d\n", signal);
     fflush(fp);
     fclose(fp);
     exit(0);
  }
}

int main() {
  fp = fopen("a.log","w+");
  if (signal(SIGTERM,signalHandler) == SIG_ERR) 
     printf("\n SIGTERM CAUGHT");
  for (int i=0; ;i++) {
      fprintf(fp,"ok..\n");
      fflush(fp);
      sleep(2);
  }
}
Comment 5 Alexander 2023-12-22 19:14:06 UTC
Thanks for the code, I tested it. On my machine it does not respond to system reboots. That is, the SIGTERM signal does not reach the program. In the log there is only "ok..". If I send a signal explicitly (killall -sTERM a.out) “Received signal is: 15” appears in the log. I tested it on different kernels: both distribution and self-assembled ones. Both with user rights for the program and with superuser rights by setting set uid root. Maybe it's a distribution feature (I'm using Debian sid) that the signal reaches systemd, but not other programs?
Comment 6 Rajesh 2023-12-25 10:19:28 UTC
H(In reply to Alexander from comment #5)
> Thanks for the code, I tested it. On my machine it does not respond to
> system reboots. That is, the SIGTERM signal does not reach the program. In
> the log there is only "ok..". If I send a signal explicitly (killall -sTERM
> a.out) “Received signal is: 15” appears in the log. I tested it on different
> kernels: both distribution and self-assembled ones. Both with user rights
> for the program and with superuser rights by setting set uid root. Maybe
> it's a distribution feature (I'm using Debian sid) that the signal reaches
> systemd, but not other programs?

Hi Alexander,

Merry xmas and I come bearing gifts! 

So signal is not a posix standard and hence it's not working across different flavours.

Sigaction is the posix standard. There is a lot to sigaction and hence I won't be going down that road. Instead let me give a a dummy code which works and also a hint.

Your process below needs to rely on systemd. If I run as a standalone process it sometimes misses the signal. So the realiable way is to configure the below as a systemd. I have given below the systemd config too for my below code that runs as service "dummy.service". Refer to systemd docs on how to configure. 

Note: Tested the below in Ubuntu 22.04.4, deian trixie sid (test)


 /* Code for handling sigaction 
 * Create those directories that we are removing e.g rmdir("session");
 */

#include <signal.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

volatile sig_atomic_t FLAG; 
volatile sig_atomic_t fd;

void signalHandler(int signal) {
   FLAG=0;
   write(fd,"Shutdown\n",9);
   rmdir("delete-this");
   rmdir("session");
   fsync(fd);
   _exit(0);
}

int main() {
   FLAG = 1;
   struct sigaction act;
   act.sa_handler = &signalHandler;
   sigaction(SIGTERM,&act,NULL); //calling sigaction to follow posix std
   fd = fopen("/home/duke/output.log",O_WRONLY|O_CREAT|O_TRUNC,0644);
   while (FLAG) {
      write(fd,"Write\n",6);
      sleep(1);
   }
}


/* Systemd config

Note that you this is just a sample and should never be used as is in a prodcution as I didn't give much thought about running this in production as this is a demo */


[Unit]
Description="test"

[Service]
Type=simple
User=root
WorkingDirectory=/home/duke
ExecStart=/home/rajesh/rebooter
Restart= always
RestartSec=3

[Install]
WantedBy=reboot.target


Now you run systemctl start dummy.service and reboot and your directories should go away and an entry in the output.log

Note You need to log in before you can comment on or make changes to this bug.