Message ID | 1560867883-3726-3-git-send-email-philippe.reynes@softathome.com |
---|---|
State | Changes Requested |
Headers | show |
Series | add a new handler ubiswap to swap several ubi volume | expand |
Hi Philippe, On 18/06/19 16:24, Philippe Reynes wrote: > This new handler ubiswap swap the name of several ubi volume > in atomic way after all images were flashed. This handler is > seen as a script by swupdate, and all the date are provided > by the sw-description file. > > Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com> > --- > doc/source/handlers.rst | 20 ++++++++++ > handlers/ubivol_handler.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 120 insertions(+) > > diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst > index 03c0a69..65339b1 100644 > --- a/doc/source/handlers.rst > +++ b/doc/source/handlers.rst > @@ -163,6 +163,26 @@ However, please note the following limitations: > - Atomic renames are only possible and permitted for volumes residing > on the same UBI device. > > +There is a handler ubiswap that allow to do an atomic swap for several > +ubi volume after all the images were flashed. This handler is a script > +for the point of view of swudate, so the node that provide it the data > +should be added in the section scripts. > + > +:: > + > + scripts: ( > + { > + type = "ubiswap"; > + properties: { > + num-swap = 2; > + swap-first-name-0 = "boot"; > + swap-second-name-0 = "boot_r"; > + swap-first-name-1 = "kernel"; > + swap-second-name-1 = "kernel_r"; > + }, > + }, > + ); > + This looks quite hard-coded and redundant. Why a user should both set all names and provide num-swap ? (Apart that it is easier, of course !) Why cannot be found by the handler ? The general code is able to handle multiple properties in an array and put them in a list (check swu_forward for example). That is you can also do in tis way: properties: { swap-0 = ["boot", "boot_r"]; swap-1 = ["kernel", "kernel_r"]; } and you can iterate all swap-%d until none is found. Something like: count = 0; while (1) { snprintf(prop, sizeof(prop), "swap-%d", count); volumes = dict_get_list(&img->properties, prop); and then you iterate the list to get first and second name. > > Lua Handlers > ------------ > diff --git a/handlers/ubivol_handler.c b/handlers/ubivol_handler.c > index 60851e5..4f9bcf4 100644 > --- a/handlers/ubivol_handler.c > +++ b/handlers/ubivol_handler.c > @@ -373,6 +373,104 @@ static int adjust_volume(struct img_type *cfg, > return 0; > } > > +static int swap_volume(struct img_type *img, > + void __attribute__ ((__unused__)) *data) > +{ > + struct flash_description *flash = get_flash_info(); > + libubi_t libubi = flash->libubi; > + char *str_num_swap; > + int i, num_swap; > + char *first_name, *second_name; > + struct ubi_part *first_ubi_part, *second_ubi_part; > + int first_dev_num, second_dev_num, dev_num = -1; > + int first_vol_id, second_vol_id; > + char prop[SWUPDATE_GENERAL_STRING_SIZE]; > + char masternode[UBI_MAX_VOLUME_NAME+1]; > + struct ubi_rnvol_req rnvol; > + int ret = -1; > + > + str_num_swap = dict_get_value(&img->properties, "num-swap"); > + if (!str_num_swap) { > + ERROR("property num-swap is missing"); > + goto out; > + } > + > + num_swap = atoi(str_num_swap); > + if ((num_swap < 0) || (num_swap > (UBI_MAX_RNVOL / 2))) { > + ERROR("property num-swap (%d) is invalid", num_swap); > + goto out; > + } > + > + for (i=0; i<num_swap; i++) Nitpick : as codestyle (like kernel), blank is requested. The line becomes: for (i = 0; i < num_swap; i++) Please fix this globally. > + { > + snprintf(prop, sizeof(prop), "swap-first-name-%d", i); > + first_name = dict_get_value(&img->properties, prop); > + if (!first_name) { > + ERROR("could not found property %s", prop); > + goto out; > + } > + first_ubi_part = search_volume_global(first_name); > + if (!first_ubi_part) { > + ERROR("could not found UBI volume %s", first_name); > + goto out; > + } > + first_dev_num = first_ubi_part->vol_info.dev_num; > + first_vol_id = first_ubi_part->vol_info.vol_id; > + > + snprintf(prop, sizeof(prop), "swap-second-name-%d", i); > + second_name = dict_get_value(&img->properties, prop); > + if (!second_name) { > + ERROR("could not found property %s", prop); > + goto out; > + } > + second_ubi_part = search_volume_global(second_name); > + if (!second_ubi_part) { > + ERROR("could not found UBI volume %s", first_name); > + goto out; > + } > + second_dev_num = second_ubi_part->vol_info.dev_num; > + second_vol_id = second_ubi_part->vol_info.vol_id; > + > + if (first_dev_num != second_dev_num) { > + ERROR("both device should be on the same UBI device"); > + goto out; > + } > + > + if (dev_num == -1) { > + dev_num = first_dev_num; > + snprintf(&masternode[0], sizeof(masternode), > + "/dev/ubi%d", dev_num); > + } else { > + if (dev_num != first_dev_num) { > + ERROR("all devices should be on the" > + "same UBI device"); > + goto out; > + } > + } > + > + TRACE("swap UBI volume %s <-> %s", first_name, second_name); > + > + /* swap first -> second */ > + rnvol.ents[2*i + 0].vol_id = first_vol_id; > + rnvol.ents[2*i + 0].name_len = strlen(second_name); > + strcpy(rnvol.ents[2*i + 0].name, second_name); > + > + /* swap second -> first */ > + rnvol.ents[2*i + 1].vol_id = second_vol_id; > + rnvol.ents[2*i + 1].name_len = strlen(first_name); > + strcpy(rnvol.ents[2*i + 1].name, first_name); > + > + rnvol.count = 2*i + 2; > + } > + > + ret = ubi_rnvols(libubi, masternode, &rnvol); > + if (ret) > + ERROR("cannot swap UBI volume"); > + > + out: > + return ret; > +} > + > __attribute__((constructor)) > void ubi_handler(void) > { > @@ -380,4 +478,6 @@ void ubi_handler(void) > IMAGE_HANDLER, NULL); > register_handler("ubipartition", adjust_volume, > PARTITION_HANDLER, NULL); > + register_handler("ubiswap", swap_volume, > + SCRIPT_HANDLER, NULL); > } > Best regards, Stefano Babic
diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst index 03c0a69..65339b1 100644 --- a/doc/source/handlers.rst +++ b/doc/source/handlers.rst @@ -163,6 +163,26 @@ However, please note the following limitations: - Atomic renames are only possible and permitted for volumes residing on the same UBI device. +There is a handler ubiswap that allow to do an atomic swap for several +ubi volume after all the images were flashed. This handler is a script +for the point of view of swudate, so the node that provide it the data +should be added in the section scripts. + +:: + + scripts: ( + { + type = "ubiswap"; + properties: { + num-swap = 2; + swap-first-name-0 = "boot"; + swap-second-name-0 = "boot_r"; + swap-first-name-1 = "kernel"; + swap-second-name-1 = "kernel_r"; + }, + }, + ); + Lua Handlers ------------ diff --git a/handlers/ubivol_handler.c b/handlers/ubivol_handler.c index 60851e5..4f9bcf4 100644 --- a/handlers/ubivol_handler.c +++ b/handlers/ubivol_handler.c @@ -373,6 +373,104 @@ static int adjust_volume(struct img_type *cfg, return 0; } +static int swap_volume(struct img_type *img, + void __attribute__ ((__unused__)) *data) +{ + struct flash_description *flash = get_flash_info(); + libubi_t libubi = flash->libubi; + char *str_num_swap; + int i, num_swap; + char *first_name, *second_name; + struct ubi_part *first_ubi_part, *second_ubi_part; + int first_dev_num, second_dev_num, dev_num = -1; + int first_vol_id, second_vol_id; + char prop[SWUPDATE_GENERAL_STRING_SIZE]; + char masternode[UBI_MAX_VOLUME_NAME+1]; + struct ubi_rnvol_req rnvol; + int ret = -1; + + str_num_swap = dict_get_value(&img->properties, "num-swap"); + if (!str_num_swap) { + ERROR("property num-swap is missing"); + goto out; + } + + num_swap = atoi(str_num_swap); + if ((num_swap < 0) || (num_swap > (UBI_MAX_RNVOL / 2))) { + ERROR("property num-swap (%d) is invalid", num_swap); + goto out; + } + + for (i=0; i<num_swap; i++) + { + snprintf(prop, sizeof(prop), "swap-first-name-%d", i); + first_name = dict_get_value(&img->properties, prop); + if (!first_name) { + ERROR("could not found property %s", prop); + goto out; + } + first_ubi_part = search_volume_global(first_name); + if (!first_ubi_part) { + ERROR("could not found UBI volume %s", first_name); + goto out; + } + first_dev_num = first_ubi_part->vol_info.dev_num; + first_vol_id = first_ubi_part->vol_info.vol_id; + + snprintf(prop, sizeof(prop), "swap-second-name-%d", i); + second_name = dict_get_value(&img->properties, prop); + if (!second_name) { + ERROR("could not found property %s", prop); + goto out; + } + second_ubi_part = search_volume_global(second_name); + if (!second_ubi_part) { + ERROR("could not found UBI volume %s", first_name); + goto out; + } + second_dev_num = second_ubi_part->vol_info.dev_num; + second_vol_id = second_ubi_part->vol_info.vol_id; + + if (first_dev_num != second_dev_num) { + ERROR("both device should be on the same UBI device"); + goto out; + } + + if (dev_num == -1) { + dev_num = first_dev_num; + snprintf(&masternode[0], sizeof(masternode), + "/dev/ubi%d", dev_num); + } else { + if (dev_num != first_dev_num) { + ERROR("all devices should be on the" + "same UBI device"); + goto out; + } + } + + TRACE("swap UBI volume %s <-> %s", first_name, second_name); + + /* swap first -> second */ + rnvol.ents[2*i + 0].vol_id = first_vol_id; + rnvol.ents[2*i + 0].name_len = strlen(second_name); + strcpy(rnvol.ents[2*i + 0].name, second_name); + + /* swap second -> first */ + rnvol.ents[2*i + 1].vol_id = second_vol_id; + rnvol.ents[2*i + 1].name_len = strlen(first_name); + strcpy(rnvol.ents[2*i + 1].name, first_name); + + rnvol.count = 2*i + 2; + } + + ret = ubi_rnvols(libubi, masternode, &rnvol); + if (ret) + ERROR("cannot swap UBI volume"); + + out: + return ret; +} + __attribute__((constructor)) void ubi_handler(void) { @@ -380,4 +478,6 @@ void ubi_handler(void) IMAGE_HANDLER, NULL); register_handler("ubipartition", adjust_volume, PARTITION_HANDLER, NULL); + register_handler("ubiswap", swap_volume, + SCRIPT_HANDLER, NULL); }
This new handler ubiswap swap the name of several ubi volume in atomic way after all images were flashed. This handler is seen as a script by swupdate, and all the date are provided by the sw-description file. Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com> --- doc/source/handlers.rst | 20 ++++++++++ handlers/ubivol_handler.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+)