hi folks

I've been looking into a candidate solution for supporting
the ordering of property values in the SMF repository.
The subject of the ordering of property values has come
up here a few times before, for example see:

http://www.opensolaris.org/jive/thread.jspa?messageID=53690&#53690

A key advantage of preserving ordering would be that
it would no longer be necessary to store order-sensitive
multiply-valued values in a single astring property using
a separator to delimit the individual values.

The issue is that at present, SMF properties with multiple values
are not stored in the repository in a manner which allows the
values to be retrieved in the same order in which they were
added. To support such ordering, a few things need to
be done. Firstly, libscf, more specifically, scf_entry_add_value() -
the function which collates values for commitment to
the repository - needs to collect values in the order in
which they were added. At present it adds values at
the head of the list for commitment, so that we commit
values in reverse order. This part is easily fixed by adding
new values at the tail of the list. From there, the repository
protocol needs to do the right thing with respect to ordering,
which I believe it does. Finally, at the backend, in the sqlite
.db files which comprise the repository, we need to store values
in such a way that they can be retrieved in order.
At present, property values are stored as multiple
rows in a table (value_tbl), and are associated with a
particular property via an identifier they share
(value_id). When these are retrieved, we  carry out a SELECT
operation which selects all values with the required value_id,
specifying no particular order (though it seems like
we get the right order due to sqlite implementation details
which we shouldn't rely on).

To support ordering at the repository level, I suggest
adding an additional column to the value_tbl,  named
value_order. When we add property values, we would
need to also specify ordering (0, 1, 2, ..) for this column.
On retrieval then, we can modify the backend SELECT
statement to ORDER BY the value_order column and
thus ordering is preserved.

A major concern with such a change of course is
handling upgrade to a new repository format, while
also supporting downgrade from the new format to the
previous format. To ensure svc.configd can deal
with the repository format, the repository carries a
schema version number which must match the version
encoded in svc.configd in order for the repository
to be usable. My suggestion is that we do not bump
this version number for this change. A downgraded
svc.configd can actually handle a repository with the
extra value_order column perfectly (it merely ignores it).
It might make sense introduce a minor version number into
the schema_version table, to reflect that the schema
has changed, but not in an incompatible manner.

This leaves the issue of upgrading to the new
repository format. Ideally, we would like to
add the new column as soon as the repository
is writable on upgrade, but we have to deal
with a few complications:

- during boot, we need to read property values prior to the
point when we can do the repository upgrade (i.e. prior to
the repository being writable)
- the version of sqlite used does not support the ADD COLUMN
command, so adding a new column to the value_tbl
is not straightforward.

To address the first issue, we need to keep track of
whether upgrade has been carried out for a particular
backend. This is important, because during first boot
post-upgrade, we will need to read values before
we can write to (and upgrade) the repository. This
means we need to modify the SELECT statement
that retrieves values based on whether the upgrade
has been done (since prior to upgrade it cannot use
the ORDER BY value_order clause in the SELECT
statement that retrieves values).

To address the second issue, we just need to do a more
complex dance of creating a temporary table which includes the
new column, populate it with the value_tbl values, delete
the original value_tbl, create the new value_tbl (with the
additional column), populate it with the values from the
temporary value table, and finally delete the temporary value
table. Testing indicates this just takes a few seconds.

I've posted a webrev which contains what I have so
far:

http://cr.opensolaris.org/~amaguire/smf_values/

I've confirmed this approach works, and supports
upgrade/downgrade, but I think it needs some additional
investigation to be determined sufficiently robust (I still see
one complaint about the lack of a value_order column during
first boot post-bfu). I'm assuming we'd also need to assess the
impact on performance (if any) that adding an additional column
to the value table would have, but I  thought it'd be useful to have
a rough candidate solution to start discussing how/if the ordering
issue can be resolved. 

Comments are appreciated!

Alan

Reply via email to