@@ -738,6 +738,13 @@ As a general rule, swupdate doesn't copy out a file if the destination path
doesn't exists. This behavior could be changed using the special property
"create-destination".
+As another general rule, swupdate installs the file directly to the specified
+path. If the destination file is intended to be atomically installed, the
+special property "atomic-install" may be set to "true". This installs the
+file to the specified path with ".tmp" apppended to the filename. In the case
+where a file already exists with the specified path, the atomic install prevents
+the original file from being overwritten until the temp file is installed.
+
Scripts
-------
@@ -206,6 +206,7 @@ static int install_raw_file(struct img_type *img,
void __attribute__ ((__unused__)) *data)
{
char path[255];
+ char tmp_path[255];
int fdout;
int ret = 0;
int use_mount = (strlen(img->device) && strlen(img->filesystem)) ? 1 : 0;
@@ -237,6 +238,13 @@ static int install_raw_file(struct img_type *img,
}
}
+ if (strtobool(dict_get_value(&img->properties, "atomic-install"))) {
+ if (snprintf(tmp_path, sizeof(path), "%s%s", img->path, ".tmp") >= (int)sizeof(path)) {
+ ERROR("Temp path too long: %s%s", img->path, ".tmp");
+ return -1;
+ }
+ }
+
TRACE("Installing file %s on %s",
img->fname, path);
@@ -249,7 +257,12 @@ static int install_raw_file(struct img_type *img,
}
}
- fdout = openfileoutput(path);
+ if (strtobool(dict_get_value(&img->properties, "atomic-install"))) {
+ fdout = openfileoutput(tmp_path);
+ }
+ else {
+ fdout = openfileoutput(path);
+ }
if (fdout < 0)
return fdout;
if (!img_check_free_space(img, fdout)) {
@@ -260,8 +273,21 @@ static int install_raw_file(struct img_type *img,
if (ret< 0) {
ERROR("Error copying extracted file");
}
+
+ if (strtobool(dict_get_value(&img->properties, "atomic-install"))) {
+ if(fsync(fdout)) {
+ ERROR("Error writing %s to disk: %s", tmp_path, strerror(errno));
+ }
+ }
+
close(fdout);
+ if (strtobool(dict_get_value(&img->properties, "atomic-install"))) {
+ if(rename(tmp_path, path)) {
+ ERROR("Error renaming %s to %s: %s", tmp_path, path, strerror(errno));
+ }
+ }
+
if (use_mount) {
swupdate_umount(DATADST_DIR);
}
Add property for raw file handler that installs file to .tmp file. Once the .tmp file is installed, it is atomically renamed to the specified file in path. This ensures that a partial install does not affect the currently installed file. Signed-off-by: Colin McAllister <colin.mcallister@garmin.com> --- doc/source/sw-description.rst | 7 +++++++ handlers/raw_handler.c | 28 +++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-)