[PATCH 4/9] delta handler: retrieve URL from core if not present

2 views
Skip to first unread message

Stefano Babic

unread,
Feb 11, 2026, 8:27:48 AM (4 days ago) Feb 11
to swup...@googlegroups.com, Stefano Babic
This solves delta update together with Hawkbit, because the URL for
the ZCK file cannot be easy set into sw-description and avoid
work-arounds on the server side. Thehandler checks for URL and if not
present, a "zckfile" with the name of the artifact (the name of ZCK file)
is retrieved from property. This is used as key to retrieve a URL from a
global list, that suricatta module for Hawkbit has provided to send to
the core when Hawkbit's answer is parsed.

Signed-off-by: Stefano Babic <stefan...@swupdate.org>
---
core/swupdate.c | 1 +
doc/source/handlers.rst | 53 ++++++++++++++++++++++++++++++++++++++++
handlers/delta_handler.c | 22 ++++++++++++++---
include/swupdate_image.h | 1 +
parser/parser.c | 1 +
5 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/core/swupdate.c b/core/swupdate.c
index cfac2f81..f8ce085c 100644
--- a/core/swupdate.c
+++ b/core/swupdate.c
@@ -297,6 +297,7 @@ static void swupdate_init(struct swupdate_cfg *sw)
LIST_INIT(&sw->bootloader);
LIST_INIT(&sw->extprocs);
LIST_INIT(&sw->swupdate_types);
+ LIST_INIT(&sw->external_urls);
strlcpy(update_type->type_name, "default", sizeof(update_type->type_name));
LIST_INSERT_HEAD(&sw->swupdate_types, update_type, next);
sw->update_type = update_type;
diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst
index ec3c9418..f3ca094c 100644
--- a/doc/source/handlers.rst
+++ b/doc/source/handlers.rst
@@ -1422,6 +1422,9 @@ The resulting header file must be packed inside the SWU.
| | | that is called after reassembling |
| | | the artifact. |
+-------------+-------------+----------------------------------------------------+
+ | zckfile | string | name of the external ZCK file. This is used only |
+ | | | if URL is not present or it is set to "dynamic" |
+ +-------------+-------------+----------------------------------------------------+
| max-ranges | string | Max number of ranges that a server can |
| | | accept. Default value (150) should be ok |
| | | for most servers. |
@@ -1464,6 +1467,56 @@ Example:
};
}

+It is not always possible to set the URL into sw-description. Hawkbit for example generates a URL when an
+artifact is uploaded, and URL is not available during build. The Hawkbit connector will send the URL to
+SWUpdate, that adds it to an own list. If the URL is not present as property, or it is set to "dynamic",
+the handler asks the core for the URL for the "zckfile" property.
+Note that the URL is then not part of sw-description and for this reason not verified. Anyway, this is not a
+security issue, because all hashes related to the ZCK file are part of sw-description (as ZCK header),
+and each mismatch will stop the update.
+
+The steps to use Delta Update are:
+
+Hawkbit
+.......
+
+- create a distribution
+- add a software module to the distribution
+- in the "Upload", adds both the SWU and the ZCK file. If you have multiple artifacts that will be
+ installed as delta update, upload all required ZCK.
+
+sw-description
+..............
+
+Use the `dynamic` keyword to set the URL in the properties. SWUpdate will then check if there is
+a URL for the value of `zckfile`. Value of zckfile must be set to the filename of the ZCK file uploaded
+to the Hawkbit server. Example:
+
+::
+
+ images: (
+ {
+ filename = "software.zck.header";
+ type = "delta";
+
+ device = "/dev/sde4";
+ properties: {
+ url = "dynamic";
+ chain = "raw";
+ source = "/dev/sde5";
+ zckloglevel = "info";
+ source-size = "detect";
+ zckfile = "software.rootfs.ext4.zck";
+ };
+ }
+
+
+Hawkbit has also some DOS countermeasures that should be deactivated, else Hawkbit thinks to be under attack and does not
+deliver the required chunks.
+
+hawkbit.server.security.dos.filter.enabled=false
+hawkbit.server.security.dos.maxStatusEntriesPerAction=-1
+
Memory issue with zchunk
........................

diff --git a/handlers/delta_handler.c b/handlers/delta_handler.c
index 2039413e..affbedd2 100644
--- a/handlers/delta_handler.c
+++ b/handlers/delta_handler.c
@@ -306,17 +306,33 @@ static int delta_retrieve_attributes(struct img_type *img, struct hnd_priv *priv

priv->zckloglevel = ZCK_LOG_DDEBUG;
priv->url = dict_get_value(&img->properties, "url");
+
+ /*
+ * Check if URL is not set and must be retrieved from the global list
+ */
+ if (!priv->url || !strcmp(priv->url, "dynamic")) {
+ char *zckfile;
+ zckfile = dict_get_value(&img->properties, "zckfile");
+ if (!zckfile) {
+ ERROR("External URL is not set neither in sw-description nor passed as URL");
+ return -EINVAL;
+ }
+ priv->url = dict_get_value(img->urls, zckfile);
+ if (priv->url) {
+ TRACE("ZCK Url set to %s", priv->url);
+ }
+ }
+
priv->srcdev = dict_get_value(&img->properties, "source");
priv->chainhandler = dict_get_value(&img->properties, "chain");
+
if (!priv->url || !priv->srcdev ||
!priv->chainhandler || !strcmp(priv->chainhandler, handlername)) {
ERROR("Wrong Attributes in sw-description: url=%s source=%s, handler=%s",
priv->url, priv->srcdev, priv->chainhandler);
- free(priv->url);
- free(priv->srcdev);
- free(priv->chainhandler);
return -EINVAL;
}
+
errno = 0;
if (dict_get_value(&img->properties, "max-ranges"))
priv->max_ranges = strtoul(dict_get_value(&img->properties, "max-ranges"), NULL, 10);
diff --git a/include/swupdate_image.h b/include/swupdate_image.h
index 1bb37dc8..e9e9b023 100644
--- a/include/swupdate_image.h
+++ b/include/swupdate_image.h
@@ -70,6 +70,7 @@ struct img_type {
* that are alive during an installation. They can be used by handlers
*/
struct dict *bootloader;/* pointer to swupdate_cfg's bootloader dict for handlers to modify */
+ struct dict *urls; /* pointer to swupdate_cfg's external URL */
lua_State *L; /* pointer to swupdate_cfg's LUa state created by parser */

long long partsize;
diff --git a/parser/parser.c b/parser/parser.c
index 84bf036c..6666ff21 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -406,6 +406,7 @@ static int is_image_higher(struct swver *sw_ver_list,
static void set_img_globals(struct img_type *img, struct swupdate_cfg *sw)
{
img->bootloader = &sw->bootloader;
+ img->urls = &sw->external_urls;
img->L = sw->lua_state;
}

--
2.43.0

Reply all
Reply to author
Forward
0 new messages