diff options
Diffstat (limited to 'doc/upgrades+errors.txt')
-rw-r--r-- | doc/upgrades+errors.txt | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/doc/upgrades+errors.txt b/doc/upgrades+errors.txt new file mode 100644 index 000000000..09b5bd5ee --- /dev/null +++ b/doc/upgrades+errors.txt @@ -0,0 +1,220 @@ +From ian Wed Nov 16 15:12:56 1994 +X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil] + [nil "Wed" "16" "November" "1994" "15:12:56" nil "ian" "ian" "" nil "dpkg - upgrades and error handling, take 2" "^To:" nil nil "11" nil nil nil nil] + nil) +To: Debian dpkg list <debian-dpkg@pixar.com> +Subject: dpkg - upgrades and error handling, take 2 + +Here is a revised scheme for upgrade procedure and error handling. + +If you can see any serious problems with this please say so; if there +are no compelling reasons not to I intend to implement the following. + + +Procedure for new unpack: + * Run the preinst script (argument: `install'). + * Back up the conffiles. + * Unpack the files in the package. +This leaves the package in the `unpacked but not configured' +state. + +If the preinst fails the installation is aborted immediately, leaving +the package in whatever state it was originally. The preinst should +clean up after its own failure. + +If the conffiles can't be backed up then any which have been are +restored to their original names, if possible, and the postrm script +is run if there is one (argument: `abort-install'). This leaves the +package in its original state. + +If the unpack fails any files already unpacked are removed, the +conffiles are restored to their original names, and the postrm is run +(argument: `abort-install'). Again, the package remains in its +original state. + +Errors found when running the postrm are ignored. + + +Procedure for configuration: + * Do the conffile updating, including prompting, as in the spec. + * Run the postinst (argument: `configure'). + +If the conffile updating fails anything that has been done is undone +if possible and the package is left in the `unpacked but not +configured' state. + +If the postinst fails dpkg gives up and leaves the package in the +`postinst failed' state. Next time it will just rerun the +postinst; if the postinst has a bug a new *.deb can be provided. In +that case installation of the new *.deb will proceed almost as if it +were a normal upgrade. + + +Procedure for removal: + * Run the prerm (argument: `remove'). + * Delete the files in the package and any resulting empty + directories. + * Run the postrm (argument: `remove'). + +If the prerm fails dpkg leaves the package in the original state; if +the user asks again to remove the package the prerm will be run again. + +If the deletion fails the removal is aborted, and the package left in +the `removal failed' state. + +If the postrm fails dpkg leaves the package in the `removal failed' +state. + +If the package is in the `removal failed' state to start with it will +start again with deleting the files and empty directories and rerun +the postrm. + +If the postrm has a bug a new *.deb must be installed first (using the +upgrade procedure) and then removed. This is so that a working postrm +script is provided. + + +Procedure for upgrade: + * Run the old prerm script (arguments: `upgrade <new-version>'). + * Move aside all existing files (not directories) for the + package being overwritten. + * Run the old postrm script (arguments: `upgrade <new-version>'). + * Run the new preinst script (arguments: `upgrade <old-version>'). + * Back up the conffiles. + * Unpack the files in the package. + * Remove the files which were moved aside. +This leaves the package in the `unpacked but not configured' +state. + +Errors during the removal of the files which were moved aside are +flagged, but don't cause dpkg to attempt to abort the upgrade. + +If the old prerm or postrm script fails the corresponding script from +the new package is run instead (arguments: `failed-upgrade +<old-version>'). If there is no corresponding script in the new +package the error is ignored. + +If any other stage fails, or if we try to use the script in the new +package because the old prerm/postrm script failed but the new script +fails too, we attempt to undo everything in reverse order, as follows: + +Unpacking the files in the package is undone by removing the files we +unpacked and any empty directories, in reverse order. Errors are +ignored. + +The conffiles backup is undone as much as possible, ignoring errors. + +The new preinst is undone by running the new postrm (arguments: +`abort-upgrade <old-version>'); errors are ignored. + +The old postrm is undone by running the old preinst (arguments: +`abort-upgrade <new-version>'); errors are ignored. + +Files we backed up are restored if possible; errors here leave the +package in the `removal failed' state. + +The old prerm is undone by running the old postinst (arguments: +`abort-upgrade <new-version>'). Errors here leave the package in the +`postinst failed' state. + + +Ian. + +From ian Wed May 17 02:14:09 +0100 1995 +X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil] + [nil nil nil nil nil nil nil nil nil nil nil nil "^To:" nil nil nil nil nil nil nil] + nil) +To: Debian developers list <debian-devel@pixar.com> +Subject: New dpkg overwriting handling + +Here is a comment that describes how I plan to have the new C dpkg act +with respect to overwriting, upgrades, &c. + +The sequence of events during upgrade will change, because the removal +of the old package and the installation of the new will take place +together. So we have, + + (noninteractive, during `dpkg --unpack' ...) + old prerm + new preinst + unpack new archive, possibly overwriting old files + delete any files in the old but not the new package + old postrm + run `postrm disappear' for any vanished packages, then forget them + + (interactive, during `dpkg --configure' ...) + conffile updates + new postinst + +Furthermore, conffiles will not be backed up before unpack and have +the user's old version hang around as `.dpkg-tmp'; instead, the old +file will be left in place and the new one extracted into `.dpkg-new'. +It will only be installed (if desired) at a conffile update. + +Thanks to Bruce for providing nice tar-in-a-function code that will +allow me to handle each file individually rather than having tar splat +them all out (and often do it buggily anyway). + +Ian. + + /* + * Now we unpack the archive, backing things up as we go. + * For each file, we check to see if it already exists. + * There are several possibilities: + * + We are trying to install a non-directory ... + * - It doesn't exist. In this case we simply extract it. + * - It is a plain file, device, symlink, &c. We do an `atomic + * overwrite' using link() and rename(), but leave a backup copy. + * Later, when we delete the backup, we remove it from any other + * packages' lists. + * - It is a directory. We move it aside and extract the file. + * Later, when we delete the backed-up directory, we remove it + * from any other packages' lists. + * + We are trying to install a directory ... + * - It doesn't exist. We create it with the appropriate modes. + * - It is a plain file or a symlink. We move it aside and create + * the directory. Later, when we delete the backup, we remove it + * from any other packages' lists. + * - It exists as a directory. We do nothing. + * + * Install non-dir Install dir + * Exists not X C + * File/node/symlink LXR BCR + * Directory BXR - + * + * C: create directory + * X: extract file/node/link + * LX: atomic overwrite leaving backup + * B: ordinary backup + * R: later remove from other packages' lists + * -: do nothing + * + * After we've done this we go through the remaining things in the + * lists of packages we're trying to remove (including the old + * version of the current package). This happens in reverse order, + * so that we process files before the directories (or symlinks-to- + * directories) containing them. + * + If the thing is a conffile then we leave it alone for the purge + * operation. + * + Otherwise, there are several possibilities too: + * - The listed thing does not exist. We ignore it. + * - The listed thing is a directory or a symlink to a directory. + * We delete it only if it isn't listed in any other package. + * - The listed thing is not a directory or a symlink to one (ie, + * it's a plain file, device, pipe, &c, or a symlink to one, or a + * dangling symlink). We delete it. + * The removed packages' list becomes empty (of course, the new + * version of the package we're installing will have a new list, + * which replaces the old version's list). + * + * If at any stage we remove a file from a package's list, and the + * package isn't one we're already processing, and the package's + * list becomes empty as a result, we `vanish' the package. This + * means that we run its postrm with the `disappear' argument, and + * put the package in the `not-installed' state. Its conffiles are + * ignored and forgotten about. + * + * NOTE THAT THE OLD POSTRM IS RUN AFTER THE NEW PREINST, since the + * files get replaced `as we go'. + */ + |