[Rpm-maint] [PATCH 2/2] Add a call for changing package header information.

Aleksei Nikiforov darktemplar at altlinux.org
Fri Mar 30 14:11:06 UTC 2018


Hi

29.03.2018 15:55, Aleksei Nikiforov пишет:
> Hi
> 
> 29.03.2018 15:51, Jeff Johnson пишет:
>>
>>
>>> On Mar 29, 2018, at 4:46 AM, Aleksei Nikiforov 
>>> <darktemplar at altlinux.org>
>>
>> ...
>>
>>>>>> Adding AUTOINSTALLED through a transaction like this is far more 
>>>>>> complex than necessary, particularly since rpm itself does not 
>>>>>> need nor use that tag for any purpose
>>>>> I've looked at librpm API documentation a few moments ago and found 
>>>>> rpmdbSetIteratorRewrite + rpmdbSetIteratorModified. Did you mean 
>>>>> these interfaces or something else I missed which could be used for 
>>>>> changing headers in rpm db?
>>>> Yes, those interfaces. Note that those interfaces are traversed only 
>>>> in the case of a replaced file, which only rarely happens (multilib 
>>>> and sloppy packaging are the two common cases that come to mind).
>>>
>>
>> Apologies for not being precise.
>>
>> Within rpm code, those interfaces are traversed only in the case of a 
>> replaced file, and
>> hence might be considered "lightly tested" or buggy.
>>
>>> Patch 2 is used to provide interface which can be used for 
>>> implementation of utilities like 'apt-mark auto' or 'apt-mark 
>>> manual'. In that case no files are changed, no packages are actually 
>>> reinstalled, only 1 header tag value is changed (or added, if tag 
>>> AUTOINSTALLED was missing).
>>>
>>>>> As for doing it within transaction, why not? As far as I can see 
>>>>> almost every action on RPM db is done on open transaction, 
>>>>> including rpmtsRebuildDB and rpmdbSetIteratorRewrite + 
>>>>> rpmdbSetIteratorModified. Atomicity and consistency of transaction 
>>>>> wouldn't hurt either.
>>>> Here are the reasons not to implement as you have done:
>>>> 0) rpm transactions are atomic/consistent only within very narrow 
>>>> meanings that have little to do with traditional meanings of ACID 
>>>> database transactions. E.g. The underlying Berkeley DB uses a CDB, 
>>>> not a transactional model. There are no logs nor rollbacks nor 
>>>> commit/discard events. Atomicity is only within an exclusive fcntl 
>>>> write lock, and consistency is only de facto, as in there is exactly 
>>>> one add/del operation per transaction element, with no well defined 
>>>> way to hide, say, an add/del operation until the rpm transaction is 
>>>> committed.
>>>> 1) the rpmte interfaces aren't all that useful or compelling as an 
>>>> API. I can't think of any application that has used/needed access to 
>>>> rpmte transaction elements, because applications already have the 
>>>> headers from which the transaction was composed.
>>>> 2) There isn't any known usage case within rpm for AUTOINSTALL, nor 
>>>> is there any means to compute the value within rpm which has no 
>>>> depsolver.
>>>> Why should rpm start managing apt+rpm (my guess at what alt is 
>>>> doing) data? If apt wishes AUTOINSTALL, then apt, not rpm, should 
>>>> manage that data, and there are already sufficient API calls to 
>>>> perform that management task.
>>>
>>> Yes, depsolver is external, outside of librpm, but it is desired to 
>>> keep all information in one database, including AUTOINSTALL tag, and 
>>> this tag may be needed to be changed after package installation.
>>>
>>> How can it be implemented other way? If rpmdbSetIteratorRewrite + 
>>> rpmdbSetIteratorModified only works when files are changed, then this 
>>> wouldn't work for this use-case.
>>>
>>
>> Just do what markReplacedFile() does, but in apt-mark, outside of rpm 
>> code.
>>
> 
> Thanks for clarification, I'll try doing it and see if it works for me.
> 

I've tried using rpmdbSetIteratorRewrite + rpmdbSetIteratorModified and 
it didn't work for me.

I've tried calling headerDel + headerPutUint32, headerGet + 
headerGetUint32 + writing new value to the pointed memory, headerMod. 
Every time it fails to write modified header, function headerExport hits 
following condition:

	if (count != (rdlen + entry->info.count + drlen))
		goto errxit;
	}

and returns NULL to function miFreeHeader.

I was hitting similar issue when implementing current patches and worked 
around it by making a copy of header and working with it:

	case TR_CHANGED:
		tmp_h = rpmteDBHeader(te);
		h = headerCopy(tmp_h);
		headerFree(tmp_h);
		break;

But I can't find a way to modify header returned by rpmdbNextIterator() 
and make rpmdbFreeIterator() successfully save changes, or a way to 
replace whole header from rpmdbMatchIterator. Am I missing some way to 
modify or replace header and successfully write changes to rpm db?

>> 73
>>>> 73 de Jeff
>>>>> Best regards
>>>>> Aleksei Nikifo
> 
> Best regards
> Aleksei Nikiforov
> _______________________________________________
> Rpm-maint mailing list
> Rpm-maint at lists.rpm.org
> http://lists.rpm.org/mailman/listinfo/rpm-maint

Best regards
Aleksei Nikiforov


More information about the Rpm-maint mailing list