Modify

Opened 11 years ago

Closed 9 years ago

Last modified 4 years ago

#1908 closed defect (worksforme)

ipkg upgrade doesn't correctly detect new versions

Reported by: netprince (at) vt (dot) edu Owned by: developers
Priority: normal Milestone: Barrier Breaker 14.07
Component: base system Version:
Keywords: ipkg upgrade Cc:

Description

I have written a package called 'customizer' which configures a base installation of openwrt with all my preferences. When I make updates to my scripts/preferences, I can usually update my clients by running 'ipkg upgrade customizer'. With kamikaze, 'ipkg upgrade' does not detect the newer version of customizer:

root@tester:~# ipkg list_installed | grep "customizer"
customizer - 139 -
root@tester:~# ipkg -V 3 upgrade customizer
pkg_info_preinstall_check: updating arch priority for each package
pkg_info_preinstall_check: update file owner list
best installation candidate for customizer
 adding customizer to providers
  customizer arch=mipsel arch_priority=10 version=141
  customizer arch=mipsel arch_priority=10 version=139
 Found a valid candidate for the install: customizer 141
 Found a valid candidate for the install: customizer 139
comparing visible versions of pkg customizer:
        139 is installed
        139 is available
        0 was comparison result
Package customizer (139) installed in root is up to date.
Configuring unpacked packages
Nothing to be done
Done.
hash_table[pkg-hash] n_buckets=0 n_elements=169 max_conflicts=0 n_conflicts=0
hash_table[file-hash] n_buckets=0 n_elements=580 max_conflicts=0 n_conflicts=0
hash_table[obs-file-hash] n_buckets=0 n_elements=0 max_conflicts=0 n_conflicts=0

Note that ipkg can find the newer version, but doesn't recognize the newer version as newer.

Attachments (2)

busybox-500-ipkg-fix-pkg-comparison.patch (420.9 KB) - added by ffrrrr at gmail.com 10 years ago.
fix ipkg comparison functions. OpenWrt 500-ipkg.patch for busybox package.
busybox-526-ipkg_fix_pkg_comparison.patch (1.9 KB) - added by ffrrrr at gmail 10 years ago.
fix for ipkg comparison. you can add this patch to package/busybox/patches.

Download all attachments as: .zip

Change History (15)

comment:1 Changed 11 years ago by jirif <jiri.fojtasek@…>

Busybox ipkg is broken. It also sometime do not upgrade all packages, and stop under middle of upgrade. I have replaced bysybox ipkg by ipkg.sh from the scrpts folder. This is feature less, but do not have those problems and uprade working without those glitches.

comment:2 Changed 11 years ago by Weedy <weedy2887@…>

use $(topdir)/files to customize images, ipkg is ment for installing, not upgrading/updating.

comment:3 Changed 11 years ago by netprince (at) vt (dot) edu

I have to disagree. I know ipkg is not meant for upgrading system files, such as the kernel or base-files. But it is designed for installing/upgrading packages, and used to work really well.

As far as using $(topdir)/files, that would be limiting. When installing via ipkg, I can ask the user for preferences and adjust the installation accordingly. Plus, I dont want to have to re-install client routers every time I modify a few config files...

comment:4 Changed 10 years ago by nico

  • Resolution set to wontfix
  • Status changed from new to closed

The problem is that you still have both package versions (139 and 141) in your repository. Remove the old one (139) from the repository and try again.

comment:5 Changed 10 years ago by netprince (at) vt (dot) edu

I did try that, but this is not an issue for me anymore because I ported the ipkg package from whiterussian and saved it. All works fine with that version.

comment:6 Changed 10 years ago by ffrrrr at gmail.com

  • Resolution wontfix deleted
  • Status changed from closed to reopened

I can confirm the issue, even with only one version of a package in the repository.

I tried to upgrade updatedd on a kamikaze 7.07 from original version 2.5-4 to 2.6-5 from the OpenWrt packages repos (ipkg code is the same as in 7.09):

root@OpenWrt:~# ipkg upgrade -V 3 updatedd
pkg_info_preinstall_check: updating arch priority for each package
pkg_info_preinstall_check: update file owner list
best installation candidate for updatedd
 adding updatedd to providers
  updatedd arch=mipsel arch_priority=10 version=2.6-5  
  updatedd arch=mipsel arch_priority=10 version=2.5-4  
 Found a valid candidate for the install: updatedd 2.6-5  
 Found a valid candidate for the install: updatedd 2.5-4  
comparing visible versions of pkg updatedd:
        2.5-4 is installed 
        2.5-4 is available 
        0 was comparison result
Package updatedd (2.5-4) installed in root is up to date.
Configuring unpacked packages
Nothing to be done
Done.
hash_table[pkg-hash] n_buckets=0 n_elements=653 max_conflicts=0 n_conflicts=0
hash_table[file-hash] n_buckets=0 n_elements=296 max_conflicts=0 n_conflicts=0
hash_table[obs-file-hash] n_buckets=0 n_elements=0 max_conflicts=0 n_conflicts=0

The difference between the whiterussian ipkg-0.99.149 and kamikaze ipkg-0.99.162 (integrated in busybox) resides in archival/libipkg/pkg_hash.c in the busybox tree, in the function pkg_hash_fetch_best_installation_candidate, line 242. There is a comment just before the code.

/* Here it is usefull, if ( matching_apkgs->len > 1 ), to test if one of this matching packages has the same name of the
   needed package. In this case, I would return it for install, otherwise I will continue with the procedure */
/* The problem is what to do when there are more than a mathing package, with the same name and several version ?
   Until now I always got the latest, but that breaks the downgrade option.
   If I stop at the first one, I would probably miss the new ones 
   Maybe the way is to have some kind of flag somewhere, to see if the package been asked to install is from a file,
   or from a Packages feed.
   It it is from a file it always need to be checked whatever version I have in feeds or everywhere, according to force-down or whatever options*/
/*Pigi*/

     for (i = 0; i < matching_pkgs->len; i++) {
          pkg_t *matching = matching_pkgs->pkgs[i];
          if (constraint_fcn(matching, cdata)) {  /* We found it */
             ipkg_message(conf, IPKG_DEBUG, " Found a valid candidate for the install: %s %s  \n", matching->name, matching->version) ;
             good_pkg_by_name = matching;
             if ( matching->provided_by_hand == 1 )    /* It has been provided by hand, so it is what user want */
                break;
          }
     }

It calls the constraint_fcn which, in this case, is pkg_name_constraint_fcn.

The problem is that pkg_name_constraint_fcn only compare names, not the versions strings. So it will always return 1 as it compare 'updatedd' with 'updatedd' for example.
As a result, every candidate package is considered as a good one (good_pkg_by_name) but only the latest one is kept : that's why whith updatedd, ipkg says :

comparing visible versions of pkg updatedd:
        2.5-4 is installed 
        2.5-4 is available

because the 2.5-4 is the 2nd package version detected as candidate.

There are some lines of code after these ones, so I'm not yet sure what to do. But if you have any idea, please comment or post a patch :)

comment:7 Changed 10 years ago by ffrrrr at gmail.com

Hello,

some news :

  1. about the comment in pkg_hash_fetch_best_installation_candidate, if I understand it well, code should looks like :
    +   if ( matching_apkgs->len > 1 ) {
          for (i = 0; i < matching_pkgs->len; i++) {
               pkg_t *matching = matching_pkgs->pkgs[i];
               if (constraint_fcn(matching, cdata)) {  /* We found it */
                  ipkg_message(conf, IPKG_DEBUG, " Found a valid candidate for the install: %s %s  \n", matching->name, matching->version) ;
                  good_pkg_by_name = matching;
                  if ( matching->provided_by_hand == 1 )    /* It has been provided by hand, so it is what user want */
                     break;
               }
          }
    +   }
    
  1. The signatures of pkg_name_version_and_architecture_compare and abstract_pkg_name_compare has been modified betwenn 0.99.149 and 0.99.162 :
    -int pkg_name_version_and_architecture_compare(void *a, void *b);
    -int abstract_pkg_name_compare(void *a, void *b);
    +int pkg_name_version_and_architecture_compare(pkg_t *a, pkg_t *b);
    +int abstract_pkg_name_compare(abstract_pkg_t *a, abstract_pkg_t *b);
    

This leads to bad pointers when comparing packages :

pkg_name_version_and_architecture_compare: a=0x4fa1a8 a->name=0x4f98e8 a->name=��O b=0x4fa1ac b->name=0x503dc8 a->name=�9P

when trying to print a->name and b->name as strings with :

 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p a->name=%s b=%p b->name=%p b->name=%s\n",
               a, a->name, a->name, b, b->name, b->name);

(and pkg_print_status segfaults)

If comparison fails, available packages are not sorted so the latest one correspond to the latest version of a package.

Reverting the signatures and casts to 0.99.149 is ok. Packages get upgraded (with 'if' from 1.). Maybe it would be good to have signatures with const void * as required by qsort. These changes still have to be tested in different use cases.

Changed 10 years ago by ffrrrr at gmail.com

fix ipkg comparison functions. OpenWrt 500-ipkg.patch for busybox package.

comment:8 Changed 10 years ago by ffrrrr at gmail.com

I attached a patch fixing the issue for the version of ipkg in trunk.

The signatures of pkg_name_version_and_architecture_compare and abstract_pkg_name_compare were different between the OpenWrt ipkg version and the Handhelds one. Structures passed as parameters are pkg_t **, not pkg_t *, that's why the version was not working.

May I suggest that ipkg --version reports something like 0.99.163-OpenWrt to tell it's been adapted and patched.

comment:9 Changed 10 years ago by ffrrrr at gmail.com

attached patch was for busybox 1.7.2

comment:10 follow-up: Changed 10 years ago by SoukoussMan

I've the same problem on a busybox 1.1.3 with a ipkg 0.99.162.
Do you know how to solv this problem without change busybox version...

Thanks by advance.

Changed 10 years ago by ffrrrr at gmail

fix for ipkg comparison. you can add this patch to package/busybox/patches.

comment:11 in reply to: ↑ 10 Changed 10 years ago by anonymous

Replying to SoukoussMan:

I've the same problem on a busybox 1.1.3 with a ipkg 0.99.162.
Do you know how to solv this problem without change busybox version...

Thanks by advance.

Could you try the second patch (busybox-526-ipkg_fix_pkg_comparison.patch) ?

comment:12 Changed 9 years ago by jow

  • Resolution set to worksforme
  • Status changed from reopened to closed

OpenWrt now switched to opkg - if you still experience this problem then please open a new ticket.

comment:13 Changed 4 years ago by jow

  • Milestone changed from Attitude Adjustment 12.09 to Barrier Breaker 14.07

Milestone Attitude Adjustment 12.09 deleted

Add Comment

Modify Ticket

Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.