[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH v2 4/4] dpkg: add --memlimit option, passed to dpkg-deb



If the default decompression memory limit is too low for one's
purposes, it would be nice to be able to set a higher value to be
used in .dpkg.cfg.  This means dpkg should accept the --memlimit
option, too.

Most dpkg operation modes are actually dpkg-deb operation modes,
but that doesn't mean people don't use them directly.  Probably
all options that affect dpkg-deb should be passed to it, but it
is not worth making that happen until there is better
infrastructure for it.  The memlimit option is important because
if a machine with very little memory is regularly using packages
compressed with a high dictionary size, it should be possible to
set an appropriate default in .dpkg.cfg and always have it used.

Unfortunately, this change is not enough to achieve that:
if dpkg-deb is used directly, the configuration in .dpkg.cfg is
not used.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 man/dpkg.1       |    6 ++++++
 src/main.c       |   18 ++++++++++++++++++
 src/main.h       |    1 +
 src/processarc.c |   11 ++++++++++-
 4 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/man/dpkg.1 b/man/dpkg.1
index 4bc2ec8..dcb0a1e 100644
--- a/man/dpkg.1
+++ b/man/dpkg.1
@@ -452,6 +452,12 @@ Install a package even if it fails authenticity check.
 Ignore dependency-checking for specified packages (actually, checking is
 performed, but only warnings about conflicts are given, nothing else).
 .TP
+.BR \-M ", " \-\-memlimit= \fIbytes\fR
+Override memory usage limit for decompression.  Don't refuse to read
+lzma- or xz-compressed packages unless it would require more than
+\fIbytes\fP bytes of memory.
+This option is passed to \fBdpkg\-deb\fP(1).
+.TP
 \fB\-\-new\fP, \fB\-\-old\fP
 Select new or old binary package format. This is a \fBdpkg\-deb\fP(1)
 option.
diff --git a/src/main.c b/src/main.c
index ff09fa0..969e192 100644
--- a/src/main.c
+++ b/src/main.c
@@ -136,6 +136,9 @@ usage(const struct cmdinfo *ci, const char *value)
 "  -D|--debug=<octal>         Enable debugging (see -Dhelp or --debug=help).\n"
 "  --status-fd <n>            Send status change updates to file descriptor <n>.\n"
 "  --log=<filename>           Log status changes and actions to <filename>.\n"
+"  -M|--memlimit=<n>          Don't refuse to read lzma- or xz-compressed\n"
+"                             packages unless it would require more than\n"
+"                             <n> bytes of memory (passed to dpkg-deb).\n"
 "  --ignore-depends=<package>,...\n"
 "                             Ignore dependencies involving <package>.\n"
 "  --force-...                Override problems (see --force-help).\n"
@@ -187,6 +190,7 @@ int fc_badverify = 0;
 int errabort = 50;
 const char *admindir= ADMINDIR;
 const char *instdir= "";
+const char *backend_memlimit = NULL;
 struct pkg_list *ignoredependss = NULL;
 
 static const struct forceinfo {
@@ -497,6 +501,7 @@ static const struct cmdinfo cmdinfos[]= {
   { "post-invoke",       0,   1, NULL,          NULL,      set_invoke_hook, 0, &post_invoke_hooks_tail },
   { "status-fd",         0,   1, NULL,          NULL,      setpipe, 0, &status_pipes },
   { "log",               0,   1, NULL,          &log_file, NULL,    0 },
+  { "memlimit",          'M', 1, NULL,          &backend_memlimit, NULL, 0 },
   { "pending",           'a', 0, &f_pending,    NULL,      NULL,    1 },
   { "recursive",         'R', 0, &f_recursive,  NULL,      NULL,    1 },
   { "no-act",            0,   0, &f_noact,      NULL,      NULL,    1 },
@@ -547,6 +552,7 @@ void execbackend(const char *const *argv) {
   int argc = 1;   /* for nargv */
   const char *const *arg = argv;
   bool pass_admindir = false;
+  bool pass_memlimit = false;
 
   while (*arg != NULL) {
     arg++; argc++;
@@ -561,6 +567,11 @@ void execbackend(const char *const *argv) {
     argc++;
     pass_admindir = true;
   }
+  if (strcmp(cipaction->parg, BACKEND) == 0 &&
+      backend_memlimit != NULL) {
+    argc++;
+    pass_memlimit = true;
+  }
 
   nargv = m_malloc(sizeof(char *) * (argc + 3));
   nargv[i] = m_strdup(cipaction->parg);
@@ -572,6 +583,13 @@ void execbackend(const char *const *argv) {
     sprintf(nargv[i], "--admindir=%s", admindir);
     i++, offset++;
   }
+  if (pass_memlimit) {
+    nargv[i] = m_malloc((strlen("--memlimit=") +
+                        strlen(backend_memlimit) + 1));
+    strcpy(nargv[i], "--memlimit=");
+    strcat(nargv[i], backend_memlimit);
+    i++, offset++;
+  }
 
   nargv[i] = m_malloc(2 + strlen(cipaction->olong) + 1);
   strcpy(nargv[i], "--");
diff --git a/src/main.h b/src/main.h
index cbcc2df..6181280 100644
--- a/src/main.h
+++ b/src/main.h
@@ -127,6 +127,7 @@ extern int abort_processing;
 extern int errabort;
 extern const char *admindir;
 extern const char *instdir;
+extern const char *backend_memlimit;
 extern struct pkg_list *ignoredependss;
 extern const char architecture[];
 
diff --git a/src/processarc.c b/src/processarc.c
index 2d6f320..e395239 100644
--- a/src/processarc.c
+++ b/src/processarc.c
@@ -583,7 +583,16 @@ void process_archive(const char *filename) {
   c1= m_fork();
   if (!c1) {
     m_dup2(p1[1],1); close(p1[0]); close(p1[1]);
-    execlp(BACKEND, BACKEND, "--fsys-tarfile", filename, NULL);
+    if (backend_memlimit != NULL) {
+      struct varbuf argbuf = VARBUF_INIT;
+
+      varbufprintf(&argbuf, "--memlimit=%s", backend_memlimit);
+      execlp(BACKEND, BACKEND, argbuf.buf, "--fsys-tarfile", filename, NULL);
+
+      varbuffree(&argbuf);
+    } else {
+      execlp(BACKEND, BACKEND, "--fsys-tarfile", filename, NULL);
+    }
     ohshite(_("unable to exec dpkg-deb to get filesystem archive"));
   }
   close(p1[1]);
-- 
1.6.5.rc1.199.g596ec


Reply to: