Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PPD file lost after crash #1109

Open
arnon-weinberg opened this issue Dec 9, 2024 · 6 comments
Open

PPD file lost after crash #1109

arnon-weinberg opened this issue Dec 9, 2024 · 6 comments

Comments

@arnon-weinberg
Copy link

Several times now, I've had a display manager (GDM) crash (likely nothing to do with cups), that appears to kill cups in the process, and following restart, the PPD file is gone. I am wondering if cups is interrupted at the wrong time whether it's possible that the PPD file could be lost this way?

Here is what the relevant parts of journalctl look like:

Dec 09 08:43:50 msigs cupsd[1101]: REQUEST localhost - - "POST /printers/MFCL2710DW HTTP/1.1" 200 165141 Print-Job successful-ok
Dec 09 08:44:03 msigs systemd[1]: systemd-hostnamed.service: Deactivated successfully.
-- Boot df76eb740bed4f09b46da3e1322c188d --
Dec 09 08:45:24 msigs kernel: Linux version 5.14.0-503.15.1.el9_5.x86_64 ([email protected]) (gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-2), GNU ld version 2.35.2-54.el9) #1 SMP PREEMPT_DYNAMIC Thu Nov 28 07:25:19 EST 2024
Dec 09 08:46:00 msigs systemd[1]: Starting CUPS Scheduler...
Dec 09 08:46:01 msigs cupsd[1089]: PPD file for MFCL2710DW cannot be loaded.
Dec 09 08:46:01 msigs cupsd[1089]: Missing PPD-Adobe-4.x header on line 0 of /etc/cups/ppd/MFCL2710DW.ppd.
Dec 09 08:46:01 msigs cupsd[1089]: PPD file for MFCL2710DW cannot be loaded.
Dec 09 08:46:01 msigs cupsd[1089]: Missing PPD-Adobe-4.x header on line 0 of /etc/cups/ppd/MFCL2710DW.ppd.

That is, it looks like cups was working fine immediately prior to the crash, and immediately after, not. Prior to the crash, /etc/cups/ppd/ looked like:

-rw-r--r--  1 root root 17552 2024-12-08 13:30 MFCL2710DW.ppd
-rw-r--r--  1 root root 17552 2024-12-07 12:18 MFCL2710DW.ppd.O

and immediately after, it looks like:

-rw-r--r--  1 root root     0 2024-12-09 08:44 MFCL2710DW.ppd
-rw-r--r--  1 root root 17552 2024-12-08 13:30 MFCL2710DW.ppd.O

The 0-byte file timestamp suggests it was overwritten just prior to the crash.

System Information:

>egrep PRETTY /etc/os-release
PRETTY_NAME="AlmaLinux 9.5 (Teal Serval)"
>uname -r                    
5.14.0-503.15.1.el9_5.x86_64
>rpm -q cups                 
cups-2.3.3op2-31.el9_5.x86_64
@michaelrsweet
Copy link
Member

It sounds like the whole system is crashing (not just the display manager), which is why cupsd goes away. If cupsd was in the process of updating the PPD file (why this would be, I'm not sure, but filters can tell cupsd to update attributes in the PPD file so maybe there was an active print job when things crashed?) then it is possible for the file to be truncated. We could conceivably revert the PPD file using the backup file if we cannot open the current PPD, but we need to be careful.

@arnon-weinberg
Copy link
Author

I generally think that when editing a critical file it's best to work on a copy and replace it only when done.

@michaelrsweet
Copy link
Member

That is how cupsd does things since at least CUPS 1.5 - see scheduler/file.c. New files are created with a ".N" extension, written to, flushed to disk, and then renamed (filename.ppd -> filename.ppd.O, filename.ppd.N -> filename.ppd). There isn't an atomic way to do this but we do try to do it quickly and as safely as possible.

I'm not sure what patches your distro is using, and 2.3.3 is several years old, but there isn't anything in the stock cupsd that should leave an empty PPD file on its own.

@zdohnal
Copy link
Member

zdohnal commented Dec 10, 2024

@michaelrsweet actually we do not do this in cupsdUpdatePrinterPPD() (IIUC) - we straight rename the current PPD and then open them both (latest master):

2824  /*
2825   * Get the old and new PPD filenames...
2826   */
2827 
2828   snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd.O", ServerRoot, p->name);
2829   snprintf(dstfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
2830 
2831  /*
2832   * Rename the old file and open the old and new...
2833   */
2834 
2835   if (rename(dstfile, srcfile))
2836   {
2837     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to backup PPD file for %s: %s",
2838                     p->name, strerror(errno));
2839     return (0);
2840   }
2841 
2842   if ((src = cupsFileOpen(srcfile, "r")) == NULL)
2843   {
2844     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open PPD file \"%s\": %s",
2845                     srcfile, strerror(errno));
2846     rename(srcfile, dstfile);
2847     return (0);
2848   }

so with bad luck, we can hit such result as @arnon-weinberg .

@michaelrsweet so let's use cupsdCreateConfFile() and friends there, since PPD in scheduler is in general like config file (it is saved into /etc/cups where is configuration) and it is used by cupsd, so cupsd functions make sense?

@zdohnal
Copy link
Member

zdohnal commented Dec 10, 2024

@arnon-weinberg can you provide a reproducer? By coincidence I'm Fedora/Centos Stream maintainer as well, but if you would like me to consider fixing it in Centos Stream (base of Alma AFAIK), I will need a reproducer for verifying/writing a test.

@arnon-weinberg
Copy link
Author

@zdohnal I can't reproduce a perfectly-timed crash scenario on command. Given how briefly the file is in a vulnerable state, I'm surprised that it happened by chance 4 times over the past 2 weeks - it feels like there ought to be more to the story than just bad luck... Also of note:

  • lp/printing does not actually modify the file contents (diff = none)
  • lpadmin appears to create a new file rather than truncate the existing
  • I see notes about PPD files being deprecated, so I imagine it's not worth spending much time on this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants