Преглед изворни кода

Add new --force-unsafe-io to disable safe I/O operations on unpack

This allows to not perform file system syncs before file renames
to guarantee its atomicity, which is known to cause substantial
performance degradation on some file systems, unfortunately the ones
that require the safe I/O on the first place due to their unreliable
behaviour causing zero-length files on abrupt system crashes (sudden
reboot, bus locks, pulling the plug, etc).

Using this option might improve performance at the cost of losing
data, and should thus be used with care, but that's ultimately
something for the user of the affected file systems to decide.

Closes: #584254
Guillem Jover пре 16 година
родитељ
комит
929a9c4808
5 измењених фајлова са 28 додато и 3 уклоњено
  1. 2 0
      debian/changelog
  2. 18 1
      man/dpkg.1
  3. 4 2
      src/archives.c
  4. 3 0
      src/main.c
  5. 1 0
      src/main.h

+ 2 - 0
debian/changelog

@@ -14,6 +14,8 @@ dpkg (1.15.8.6) UNRELEASED; urgency=low
   [ Guillem Jover ]
   * Disable by default usage of synchronous sync(2), as it causes undesired
     I/O on unrelated file systems. Closes: #588339, #595927, #600075
+  * Add new --force-unsafe-io to disable safe I/O operations on unpack.
+    Closes: #584254
 
   [ Updated man page translations ]
   * French (Christian Perrier). Including a typo fix

+ 18 - 1
man/dpkg.1

@@ -1,4 +1,4 @@
-.TH dpkg 1 "2010-06-02" "Debian Project" "dpkg suite"
+.TH dpkg 1 "2010-10-10" "Debian Project" "dpkg suite"
 .SH NAME
 dpkg \- package manager for Debian
 .
@@ -445,6 +445,23 @@ Overwrite one package's directory with another's file.
 \fBoverwrite\-diverted\fP:
 Overwrite a diverted file with an undiverted version.
 
+\fBunsafe\-io\fP:
+Do not perform safe I/O operations when unpacking. Currently this
+implies not performing file system syncs before file renames, which is
+known to cause substantial performance degradation on some file systems,
+unfortunately the ones that require the safe I/O on the first place due
+to their unreliable behaviour causing zero-length files on abrupt
+system crashes.
+
+\fINote\fP: For ext4, the main offender, consider using instead the
+mount option \fBnodelalloc\fP, which will fix both the performance
+degradation and the data safety issues, the latter by making the file
+system not produce zero-length files on abrupt system crashes with
+any software not doing syncs before atomic renames.
+
+\fIWarning: Using this option might improve performance at the cost of
+losing data, use with care.\fP
+
 \fBarchitecture\fP:
 Process even packages with the wrong architecture.
 

+ 4 - 2
src/archives.c

@@ -704,7 +704,8 @@ tarobject(void *ctx, struct tar_entry *ti)
       ohshite(_("error setting permissions of `%.255s'"), ti->name);
 
     /* Postpone the fsync, to try to avoid massive I/O degradation. */
-    nifd->namenode->flags |= fnnf_deferred_fsync;
+    if (!fc_unsafe_io)
+      nifd->namenode->flags |= fnnf_deferred_fsync;
 
     pop_cleanup(ehflag_normaltidy); /* fd= open(fnamenewvb.buf) */
     if (close(fd))
@@ -857,7 +858,8 @@ tar_deferred_extract(struct fileinlist *files, struct pkginfo *pkg)
 
 #if defined(USE_SYNC_SYNC)
   debug(dbg_general, "deferred extract mass sync");
-  sync();
+  if (!fc_unsafe_io)
+    sync();
 #endif
 
   for (cfile = files; cfile; cfile = cfile->next) {

+ 3 - 0
src/main.c

@@ -184,6 +184,7 @@ int fc_breaks=0, fc_badpath=0, fc_overwritediverted=0, fc_architecture=0;
 int fc_nonroot=0, fc_overwritedir=0, fc_conff_new=0, fc_conff_miss=0;
 int fc_conff_old=0, fc_conff_def=0;
 int fc_conff_ask = 0;
+int fc_unsafe_io = 0;
 int fc_badverify = 0;
 
 int errabort = 50;
@@ -214,6 +215,7 @@ static const struct forceinfo {
   { "overwrite",           &fc_overwrite                },
   { "overwrite-diverted",  &fc_overwritediverted        },
   { "overwrite-dir",       &fc_overwritedir             },
+  { "unsafe-io",           &fc_unsafe_io                },
   { "architecture",        &fc_architecture             },
   { "bad-verify",          &fc_badverify                },
   {  NULL                                               }
@@ -424,6 +426,7 @@ static void setforce(const struct cmdinfo *cip, const char *value) {
 "  conflicts [!]          Allow installation of conflicting packages\n"
 "  architecture [!]       Process even packages with wrong architecture\n"
 "  overwrite-dir [!]      Overwrite one package's directory with another's file\n"
+"  unsafe-io [!]          Do not perform safe I/O operations when unpacking\n"
 "  remove-reinstreq [!]   Remove packages which require installation\n"
 "  remove-essential [!]   Remove an essential package\n"
 "\n"

+ 1 - 0
src/main.h

@@ -131,6 +131,7 @@ extern int fc_nonroot, fc_overwritedir, fc_conff_new, fc_conff_miss;
 extern int fc_conff_old, fc_conff_def;
 extern int fc_conff_ask;
 extern int fc_badverify;
+extern int fc_unsafe_io;
 
 extern bool abort_processing;
 extern int errabort;