Final stage of dependency check - actual recursive check. First what it takes care of - circular dependency. Each patch we checking we mark as "Checking". Once I start checking patch I look is it marked as "Checking" or not, if it is - then we have circular dependency and this is error in patches themselves, so in this case I exit and print out all circle of dependency. (In recursive patching one step circular dependency is allowed).
Then I check if this patch has any non virtual packages which are not yet patched by this patch. - If all packages are virtual - then patch is not applicable. - If there is some non virtual packages but they are already patched by this patch or their descendant - then patch is already applied. After this is done we have patch with one or more packages not covered yet. Now I have to check if this patch is obsoleted or not. This is recursive check - I apply same dependency check to current patch descendant if it is not checked yet. However this is two step recursion and check calls search_up_for_approved and it calls check. Search for approved simple check all inheritance relation direct and indirect - both obsolete links and revision links. - If one of descendant approved then I mark current patch as obsoleted After this I check is this patch partially installed - there is one or more packages which were already patched by this one or its descendant. - if it is partially installed then no need to check dependency - it is already on the system! I mark it as approved right away. After this I check all incompatible patches - incompatible relations - links. - If one of them exist on the system - marked as "System" or "Partially Installed", then I mark current patch as "Incompatible" and will not install it later. - If one of them requested to be installed - marked as "Requested", then I also mark current patch as "Incompatible". - If one of them already incompatible with this one or other - marked as "Incompatible", then I also mark current patch as "Incompatible". For all other states I consider this check passed - if incompatible patch virtual or rejected for other reason then it is OK to install current. Next I check all incompatible_by links, relation to patches which declare current one as incompatible. To them I apply same rules. - If one of them exist on the system - marked as "System" or "Partially Installed", then I mark current patch as "Incompatible" and will not install it later. - If one of them requested to be installed - marked as "Requested", then I also mark current patch as "Incompatible". - If one of them already incompatible with this one or other - marked as "Incompatible", then I also mark current patch as "Incompatible". For all other states I consider this check passed - if incompatible_by patch virtual or rejected for other reason then it is OK to install current. Because of previous tree optimization this check is not recursive and pretty simple. After this done I check require relation. This is recursive check one step recursion. - If one of them Virtual - Required patch does not exist, mark current as "Requirement is not met". - If one of them marked as "Requirement is not met" - Required patch will not be installed, mark current as "Requirement is not met". - If one of them marked as "Incompatible" - Required patch will not be installed, mark current as "Requirement is not met". - If one of them marked as "Non applicable" - Required patch will not be installed because no packages to update, mark current as "Requirement is not met". (This rule now changed - this does not happen in real life, but with new patching model it may happen more often, so now it is OK in recursive patching) In all other cases - if required patch is already on the system or obsoleted or approved - this check is passed. For each required patch I take depth calculated for it during check, increment and assign it to current patch depth if it is already not bigger. Having this depths I later on sort patches by them and get right installation order in result - it is constructed the way that patch has bigger depth then one it require. At this point all dependency checks passed and I finally mark patch as "Approved"! In general this final check seems not really too complicated, but this is only because I did four tree optimization previously which in result simplify dependency tree and makes it easy to analyze. For example if I see virtual patch this mean that there is no descendant and patch really does not exist, all the other cases were eliminated by tree optimization. Same with incompatibility relation. vassun This message posted from opensolaris.org
