[PATCH] Add option MaxDlSpeed to limit download speed

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Add option MaxDlSpeed to limit download speed

Olivier Brunel
Signed-off-by: Olivier Brunel <[hidden email]>
---
 doc/pacman.8.txt      |  5 +++++
 doc/pacman.conf.5.txt |  6 ++++++
 lib/libalpm/alpm.h    |  3 +++
 lib/libalpm/dload.c   |  1 +
 lib/libalpm/handle.c  | 26 ++++++++++++++++++++++++++
 lib/libalpm/handle.h  |  1 +
 src/pacman/conf.c     | 11 +++++++++++
 src/pacman/conf.h     |  4 +++-
 src/pacman/pacman.c   | 11 +++++++++++
 src/pacman/util.c     | 45 +++++++++++++++++++++++++++++++++++++++++++++
 src/pacman/util.h     |  2 ++
 11 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 231e0bc..1890cd9 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -266,6 +266,11 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
 *\--needed*::
  Do not reinstall the targets that are already up-to-date.
 
+*\--maxdlspeed* <speed>::
+ Sets the maximum download speed to the specified speed in bytes/s, unless a
+ suffix is appended. Suffix 'k' or 'K' will count as KiB/s, 'm' or 'M' as
+ MiB/s, and 'g' or 'G' as GiB/s.
+
 
 Query Options (apply to '-Q')[[QO]]
 -----------------------------------
diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt
index c665870..49ce63b 100644
--- a/doc/pacman.conf.5.txt
+++ b/doc/pacman.conf.5.txt
@@ -201,6 +201,12 @@ Options
  bar is still based solely on the current file download.
  This option won't work if XferCommand is used.
 
+*MaxDlSpeed*::
+ Sets the maximum download speed to the specified speed in bytes/s, unless a
+ suffix is appended. Suffix 'k' or 'K' will count as KiB/s, 'm' or 'M' as
+ MiB/s, and 'g' or 'G' as GiB/s.
+ This option won't work if XferCommand is used.
+
 *CheckSpace*::
  Performs an approximate check for adequate available disk space before
  installing packages.
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 168d71b..7e4e9da 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -925,6 +925,9 @@ int alpm_option_set_local_file_siglevel(alpm_handle_t *handle, alpm_siglevel_t l
 alpm_siglevel_t alpm_option_get_remote_file_siglevel(alpm_handle_t *handle);
 int alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
 
+off_t alpm_option_get_maxdlspeed(alpm_handle_t *handle);
+int alpm_option_set_maxdlspeed(alpm_handle_t *handle, off_t speed);
+
 /** @} */
 
 /** @addtogroup alpm_api_databases Database Functions
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index 31ae82c..8c6d6af 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -295,6 +295,7 @@ static void curl_set_handle_opts(struct dload_payload *payload,
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, dload_progress_cb);
  curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, (void *)payload);
+ curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, handle->maxdlspeed);
  curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1L);
  curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 10L);
  curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, dload_parseheader_cb);
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index e9439a0..9cab5da 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -844,4 +844,30 @@ alpm_siglevel_t SYMEXPORT alpm_option_get_remote_file_siglevel(alpm_handle_t *ha
  }
 }
 
+off_t SYMEXPORT alpm_option_get_maxdlspeed(alpm_handle_t *handle)
+{
+ CHECK_HANDLE(handle, return -1);
+#ifdef HAVE_LIBCURL
+ return (off_t) handle->maxdlspeed;
+#else
+ return 0;
+#endif
+}
+
+int SYMEXPORT alpm_option_set_maxdlspeed(alpm_handle_t *handle, off_t speed)
+{
+ CHECK_HANDLE(handle, return -1);
+#ifdef HAVE_LIBCURL
+ if(speed >= 0) {
+ handle->maxdlspeed = (curl_off_t) speed;
+ return 0;
+ } else
+#else
+ if(speed == 0)
+ return 0;
+ else
+#endif
+ RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
+}
+
 /* vim: set noet: */
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index a1d0f9a..f55b6ed 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -60,6 +60,7 @@ struct __alpm_handle_t {
 #ifdef HAVE_LIBCURL
  /* libcurl handle */
  CURL *curl;             /* reusable curl_easy handle */
+ curl_off_t maxdlspeed;  /* maximum download speed (B/s) */
 #endif
 
 #ifdef HAVE_LIBGPGME
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index 25de7af..39cc15c 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -544,6 +544,16 @@ static int _parse_options(const char *key, char *value,
  }
  config->deltaratio = ratio;
  pm_printf(ALPM_LOG_DEBUG, "config: usedelta = %f\n", ratio);
+ } else if(strcmp(key, "MaxDlSpeed") == 0) {
+ off_t speed = parsesize(value);
+ if(speed < 0) {
+ pm_printf(ALPM_LOG_ERROR,
+ _("config file %s, line %d: invalid value for '%s' : '%s'\n"),
+ file, linenum, "MaxDlSpeed", value);
+ return 1;
+ }
+ config->maxdlspeed = speed;
+ pm_printf(ALPM_LOG_DEBUG, "config: maxdlspeed = %jd\n", (intmax_t) speed);
  } else if(strcmp(key, "DBPath") == 0) {
  /* don't overwrite a path specified on the command line */
  if(!config->dbpath) {
@@ -810,6 +820,7 @@ static int setup_libalpm(void)
  alpm_option_set_checkspace(handle, config->checkspace);
  alpm_option_set_usesyslog(handle, config->usesyslog);
  alpm_option_set_deltaratio(handle, config->deltaratio);
+ alpm_option_set_maxdlspeed(handle, config->maxdlspeed);
 
  alpm_option_set_ignorepkgs(handle, config->ignorepkg);
  alpm_option_set_ignoregroups(handle, config->ignoregrp);
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 2aba8bf..77353a2 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -56,6 +56,7 @@ typedef struct __config_t {
  unsigned short usesyslog;
  unsigned short color;
  double deltaratio;
+ off_t maxdlspeed;
  char *arch;
  char *print_format;
  /* unfortunately, we have to keep track of paths both here and in the library
@@ -201,7 +202,8 @@ enum {
  OP_VERBOSE,
  OP_DOWNLOADONLY,
  OP_REFRESH,
- OP_ASSUMEINSTALLED
+ OP_ASSUMEINSTALLED,
+ OP_MAXDLSPEED
 };
 
 /* clean method */
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index be52d1b..91f8500 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -194,6 +194,8 @@ static void usage(int op, const char * const myname)
  addlist(_("      --ignore <pkg>   ignore a package upgrade (can be used more than once)\n"));
  addlist(_("      --ignoregroup <grp>\n"
           "                       ignore a group upgrade (can be used more than once)\n"));
+ addlist(_("      --maxdlspeed <speed>\n"
+          "                       set the maximum download speed\n"));
  /* pass through */
  case PM_OP_REMOVE:
  addlist(_("  -d, --nodeps         skip dependency version checks (-dd to skip all checks)\n"));
@@ -713,6 +715,14 @@ static int parsearg_upgrade(int opt)
  case OP_IGNOREGROUP:
  parsearg_util_addlist(&(config->ignoregrp));
  break;
+ case OP_MAXDLSPEED:
+ {
+ off_t speed = parsesize(optarg);
+ if(speed < 0)
+ return 1;
+ config->maxdlspeed = speed;
+ break;
+ }
  default: return 1;
  }
  return 0;
@@ -929,6 +939,7 @@ static int parseargs(int argc, char *argv[])
  {"ignoregroup", required_argument, 0, OP_IGNOREGROUP},
  {"needed",     no_argument,       0, OP_NEEDED},
  {"asexplicit",     no_argument,   0, OP_ASEXPLICIT},
+ {"maxdlspeed", required_argument, 0, OP_MAXDLSPEED},
  {"arch",       required_argument, 0, OP_ARCH},
  {"print-format", required_argument, 0, OP_PRINTFORMAT},
  {"gpgdir",     required_argument, 0, OP_GPGDIR},
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 81780f7..35b4f23 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -1763,4 +1763,49 @@ int pm_vfprintf(FILE *stream, alpm_loglevel_t level, const char *format, va_list
  return ret;
 }
 
+off_t parsesize(const char *str)
+{
+ long size;
+ char *endptr;
+
+ size = strtol(str, &endptr, 10);
+ if((size == LONG_MIN || size == LONG_MAX) && errno == ERANGE) {
+ return -1;
+ }
+ if(*endptr != '\0') {
+ if(endptr[1] != '\0') {
+ return -1;
+ }
+ switch(*endptr) {
+ case 'g':
+ case 'G':
+ if(size > LONG_MAX / 1024) {
+ return -1;
+ }
+ size *= 1024;
+ /* fallthrough */
+ case 'm':
+ case 'M':
+ if(size > LONG_MAX / 1024) {
+ return -1;
+ }
+ size *= 1024;
+ /* fallthrough */
+ case 'k':
+ case 'K':
+ if(size > LONG_MAX / 1024) {
+ return -1;
+ }
+ size *= 1024;
+ break;
+ default:
+ return -1;
+ }
+ }
+ if(size < 0) {
+ return -1;
+ }
+ return (off_t) size;
+}
+
 /* vim: set noet: */
diff --git a/src/pacman/util.h b/src/pacman/util.h
index f5e37c8..7d0a897 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -82,6 +82,8 @@ int pm_vfprintf(FILE *stream, alpm_loglevel_t level, const char *format, va_list
 int pm_sprintf(char **string, alpm_loglevel_t level, const char *format, ...) __attribute__((format(printf,3,4)));
 int pm_vasprintf(char **string, alpm_loglevel_t level, const char *format, va_list args) __attribute__((format(printf,3,0)));
 
+off_t parsesize(const char *str);
+
 #endif /* _PM_UTIL_H */
 
 /* vim: set noet: */
--
2.9.3
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Add option MaxDlSpeed to limit download speed

Allan McRae
On 20/08/16 04:12, Olivier Brunel wrote:

> Signed-off-by: Olivier Brunel <[hidden email]>
> ---
>  doc/pacman.8.txt      |  5 +++++
>  doc/pacman.conf.5.txt |  6 ++++++
>  lib/libalpm/alpm.h    |  3 +++
>  lib/libalpm/dload.c   |  1 +
>  lib/libalpm/handle.c  | 26 ++++++++++++++++++++++++++
>  lib/libalpm/handle.h  |  1 +
>  src/pacman/conf.c     | 11 +++++++++++
>  src/pacman/conf.h     |  4 +++-
>  src/pacman/pacman.c   | 11 +++++++++++
>  src/pacman/util.c     | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  src/pacman/util.h     |  2 ++
>  11 files changed, 114 insertions(+), 1 deletion(-)
>


I will look at this once we have the download timeout patches in so that
we have a consistent format for downloader options.

Thanks,
Allan
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Add option MaxDlSpeed to limit download speed

Abogical
This is just a reminder for the download limit patch. It seems to have been forgotten.

Allan McRae wrote
On 20/08/16 04:12, Olivier Brunel wrote:
> Signed-off-by: Olivier Brunel <[hidden email]>
> ---
>  doc/pacman.8.txt      |  5 +++++
>  doc/pacman.conf.5.txt |  6 ++++++
>  lib/libalpm/alpm.h    |  3 +++
>  lib/libalpm/dload.c   |  1 +
>  lib/libalpm/handle.c  | 26 ++++++++++++++++++++++++++
>  lib/libalpm/handle.h  |  1 +
>  src/pacman/conf.c     | 11 +++++++++++
>  src/pacman/conf.h     |  4 +++-
>  src/pacman/pacman.c   | 11 +++++++++++
>  src/pacman/util.c     | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  src/pacman/util.h     |  2 ++
>  11 files changed, 114 insertions(+), 1 deletion(-)
>


I will look at this once we have the download timeout patches in so that
we have a consistent format for downloader options.

Thanks,
Allan

Download timeout patches were already implemented,
 so you can review the patch.

Thank you.