Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Pomozov <anatol.pomozov@gmail.com>2020-03-08 13:33:32 -0700
committerAllan McRae <allan@archlinux.org>2020-05-09 11:58:21 +1000
commitfe8e13341bdeae4a59c0270a632c29e71ae9deda (patch)
tree2e40d6b786ec2fe8bd5b878d09f2fa627c0190a8
parentcffda331adca0aedd7c1fc17d739c27fc8041a20 (diff)
Add config option to specify amount of parallel download streams
It includes pacman.conf new 'ParallelDownloads' option that specifies how many concurrent downloads cURL starts in parallel. Add alpm_option_set_parallel_downloads() ALPM function that allows to set this config option programmatically. Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--doc/pacman.conf.5.asciidoc5
-rw-r--r--etc/pacman.conf.in1
-rw-r--r--lib/libalpm/alpm.h9
-rw-r--r--lib/libalpm/handle.c15
-rw-r--r--lib/libalpm/handle.h1
-rw-r--r--src/pacman/conf.c56
-rw-r--r--src/pacman/conf.h2
7 files changed, 89 insertions, 0 deletions
diff --git a/doc/pacman.conf.5.asciidoc b/doc/pacman.conf.5.asciidoc
index 5e4602a0..3c2f1fea 100644
--- a/doc/pacman.conf.5.asciidoc
+++ b/doc/pacman.conf.5.asciidoc
@@ -209,6 +209,11 @@ Options
Disable defaults for low speed limit and timeout on downloads. Use this
if you have issues downloading files with proxy and/or security gateway.
+*ParallelDownloads*::
+ Specifies number of concurrent download streams. The value needs to be a
+ positive integer. If this config option is not set then only one download
+ stream is used (i.e. downloads happen sequentially).
+
Repository Sections
-------------------
diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in
index e3c73e13..634ecc06 100644
--- a/etc/pacman.conf.in
+++ b/etc/pacman.conf.in
@@ -35,6 +35,7 @@ Architecture = auto
#TotalDownload
CheckSpace
#VerbosePkgLists
+ParallelDownloads = 5
# PGP signature checking
#SigLevel = Optional
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index c2a069ad..5d559db1 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -903,6 +903,15 @@ int alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, int level);
int alpm_option_set_disable_dl_timeout(alpm_handle_t *handle, unsigned short disable_dl_timeout);
+/** Sets number of parallel streams to download database and package files.
+ * If the function is not called then the default value of '1' stream
+ * (i.e. sequential download) is used.
+ * @param handle the context handle
+ * @param num_streams number of parallel download streams
+ * @return 0 on success, -1 on error
+ */
+int alpm_option_set_parallel_downloads(alpm_handle_t *handle, unsigned int num_streams);
+
/** @} */
/** @addtogroup alpm_api_databases Database Functions
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 6b19a703..e3b2c911 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -856,3 +856,18 @@ int SYMEXPORT alpm_option_set_disable_dl_timeout(alpm_handle_t *handle,
#endif
return 0;
}
+
+int SYMEXPORT alpm_option_set_parallel_downloads(alpm_handle_t *handle,
+ unsigned int num_streams)
+{
+ CHECK_HANDLE(handle, return -1);
+#ifdef HAVE_LIBCURL
+ if(num_streams < 1) {
+ return -1;
+ }
+ handle->parallel_downloads = num_streams;
+#else
+ (void)num_streams; /* silence unused variable warnings */
+#endif
+ return 0;
+}
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index c343f6e0..cd7104f9 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -61,6 +61,7 @@ struct __alpm_handle_t {
/* libcurl handle */
CURL *curl; /* reusable curl_easy handle */
unsigned short disable_dl_timeout;
+ unsigned int parallel_downloads; /* number of download streams */
#endif
#ifdef HAVE_LIBGPGME
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index becbd03e..7390d741 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -114,6 +114,8 @@ config_t *config_new(void)
newconfig->remotefilesiglevel = ALPM_SIG_USE_DEFAULT;
}
+ /* by default use 1 download stream */
+ newconfig->parallel_downloads = 1;
newconfig->colstr.colon = ":: ";
newconfig->colstr.title = "";
newconfig->colstr.repo = "";
@@ -405,6 +407,32 @@ int config_set_arch(const char *arch)
}
/**
+ * Parse a string into long number. The input string has to be non-empty
+ * and represent a number that fits long type.
+ * @param value the string to parse
+ * @param result pointer to long where the final result will be stored.
+ * This result is modified if the input string parsed successfully.
+ * @return 0 in case if value parsed successfully, 1 otherwise.
+ */
+static int parse_number(char *value, long *result) {
+ char *endptr;
+ long val;
+ int invalid;
+
+ errno = 0; /* To distinguish success/failure after call */
+ val = strtol(value, &endptr, 10);
+ invalid = (errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
+ || (*endptr != '\0')
+ || (endptr == value);
+
+ if(!invalid) {
+ *result = val;
+ }
+
+ return invalid;
+}
+
+/**
* Parse a signature verification level line.
* @param values the list of parsed option values
* @param storage location to store the derived signature level; any existing
@@ -683,6 +711,33 @@ static int _parse_options(const char *key, char *value,
return 1;
}
FREELIST(values);
+ } else if(strcmp(key, "ParallelDownloads") == 0) {
+ long number;
+ int err;
+
+ err = parse_number(value, &number);
+ if(err) {
+ pm_printf(ALPM_LOG_WARNING,
+ _("config file %s, line %d: invalid value for '%s' : '%s'\n"),
+ file, linenum, "ParallelDownloads", value);
+ return 1;
+ }
+
+ if(number < 1) {
+ pm_printf(ALPM_LOG_WARNING,
+ _("config file %s, line %d: value for '%s' has to be positive : '%s'\n"),
+ file, linenum, "ParallelDownloads", value);
+ return 1;
+ }
+
+ if(number > INT_MAX) {
+ pm_printf(ALPM_LOG_WARNING,
+ _("config file %s, line %d: value for '%s' is too large : '%s'\n"),
+ file, linenum, "ParallelDownloads", value);
+ return 1;
+ }
+
+ config->parallel_downloads = number;
} else {
pm_printf(ALPM_LOG_WARNING,
_("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
@@ -851,6 +906,7 @@ static int setup_libalpm(void)
alpm_option_set_noextracts(handle, config->noextract);
alpm_option_set_disable_dl_timeout(handle, config->disable_dl_timeout);
+ alpm_option_set_parallel_downloads(handle, config->parallel_downloads);
for(i = config->assumeinstalled; i; i = i->next) {
char *entry = i->data;
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index e1df24b7..b8a451ad 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -116,6 +116,8 @@ typedef struct __config_t {
/* When downloading, display the amount downloaded, rate, ETA, and percent
* downloaded of the total download list */
unsigned short totaldownload;
+ /* number of parallel download streams */
+ unsigned int parallel_downloads;
/* select -Sc behavior */
unsigned short cleanmethod;
alpm_list_t *holdpkg;