[Libosinfo] [PATCH v3 60/60] loader: implement new semantics for entity overriding

Daniel P. Berrange berrange at redhat.com
Mon Oct 12 17:11:21 UTC 2015


This implements the new scheme for allowing entities to
be overridden. If an XML file relative path matches one
in an earlier datbase directory, the original file is
not loaded at all. Any files in a ENTITY-NAME.d will
now augment earlier data rather than replace it.

eg consider these files

1. /usr/share/libosinfo/db/os/fedoraproject.org/fedora-22.xml
2. /etc/libosinfo/db/os/fedoraproject.org/fedora-22.xml
3. $HOME/.config/libosinfo/db/os/fedoraproject.org/fedora-22.d/extra.xml

File #1 will not get loaded, because file #2 is detected
as a full override. File #2 will get loaded to define the
main Fedora 22 OS, and then file #3 will get loaded to
augment the main data.

Most of the PCI and USB device info in the local DB is
just augmenting the pci.ids and usb.ids master files,
so these need to move to .d directories now

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 .gitignore                                         |   1 +
 configure.ac                                       |  19 ++
 data/device/pcisig.com/Makefile.am                 |  22 ++
 data/device/pcisig.com/pci-1000-0012.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1013-00b8.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1022-2000.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-10ec-8029.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-10ec-8139.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1234-1111.d/Makefile.am |   1 +
 data/device/pcisig.com/pci-1274-5000.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-15ad-0710.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1af4-1000.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1af4-1001.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1af4-1002.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1af4-1003.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1af4-1009.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-1b36-0100.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-8086-100e.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-8086-2415.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-8086-25ab.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/pcisig.com/pci-8086-2668.d/Makefile.am |   1 +
 .../class.xml.in}                                  |   0
 data/device/usb.org/Makefile.am                    |   3 +-
 data/device/usb.org/usb-80ee-0021.d/Makefile.am    |   1 +
 .../class.xml.in}                                  |   0
 osinfo/osinfo_loader.c                             | 276 ++++++++++++++++++---
 42 files changed, 299 insertions(+), 41 deletions(-)
 create mode 100644 data/device/pcisig.com/pci-1000-0012.d/Makefile.am
 rename data/device/pcisig.com/{pci-1000-0012.xml.in => pci-1000-0012.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1013-00b8.d/Makefile.am
 rename data/device/pcisig.com/{pci-1013-00b8.xml.in => pci-1013-00b8.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1022-2000.d/Makefile.am
 rename data/device/pcisig.com/{pci-1022-2000.xml.in => pci-1022-2000.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-10ec-8029.d/Makefile.am
 rename data/device/pcisig.com/{pci-10ec-8029.xml.in => pci-10ec-8029.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-10ec-8139.d/Makefile.am
 rename data/device/pcisig.com/{pci-10ec-8139.xml.in => pci-10ec-8139.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1234-1111.d/Makefile.am
 create mode 100644 data/device/pcisig.com/pci-1274-5000.d/Makefile.am
 rename data/device/pcisig.com/{pci-1274-5000.xml.in => pci-1274-5000.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-15ad-0710.d/Makefile.am
 rename data/device/pcisig.com/{pci-15ad-0710.xml.in => pci-15ad-0710.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1af4-1000.d/Makefile.am
 rename data/device/pcisig.com/{pci-1af4-1000.xml.in => pci-1af4-1000.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1af4-1001.d/Makefile.am
 rename data/device/pcisig.com/{pci-1af4-1001.xml.in => pci-1af4-1001.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1af4-1002.d/Makefile.am
 rename data/device/pcisig.com/{pci-1af4-1002.xml.in => pci-1af4-1002.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1af4-1003.d/Makefile.am
 rename data/device/pcisig.com/{pci-1af4-1003.xml.in => pci-1af4-1003.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1af4-1009.d/Makefile.am
 rename data/device/pcisig.com/{pci-1af4-1009.xml.in => pci-1af4-1009.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-1b36-0100.d/Makefile.am
 rename data/device/pcisig.com/{pci-1b36-0100.xml.in => pci-1b36-0100.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-8086-100e.d/Makefile.am
 rename data/device/pcisig.com/{pci-8086-100e.xml.in => pci-8086-100e.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-8086-2415.d/Makefile.am
 rename data/device/pcisig.com/{pci-8086-2415.xml.in => pci-8086-2415.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-8086-25ab.d/Makefile.am
 rename data/device/pcisig.com/{pci-8086-25ab.xml.in => pci-8086-25ab.d/class.xml.in} (100%)
 create mode 100644 data/device/pcisig.com/pci-8086-2668.d/Makefile.am
 rename data/device/pcisig.com/{pci-8086-2668.xml.in => pci-8086-2668.d/class.xml.in} (100%)
 create mode 100644 data/device/usb.org/usb-80ee-0021.d/Makefile.am
 rename data/device/usb.org/{usb-80ee-0021.xml.in => usb-80ee-0021.d/class.xml.in} (100%)

diff --git a/.gitignore b/.gitignore
index b663072..1cc9e2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,6 +70,7 @@ build/
 gtk-doc.make
 data/95-osinfo.rules
 data/*/*/*.xml
+data/*/*/*/*.xml
 data/pci.ids
 data/usb.ids
 tools/osinfo-detect
diff --git a/configure.ac b/configure.ac
index a7eaf26..494372c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -229,7 +229,26 @@ AC_CONFIG_FILES([
 	data/device/ibasetechnologies.net/Makefile
 	data/device/ibm.com/Makefile
 	data/device/pcisig.com/Makefile
+	data/device/pcisig.com/pci-1000-0012.d/Makefile
+	data/device/pcisig.com/pci-1013-00b8.d/Makefile
+	data/device/pcisig.com/pci-1022-2000.d/Makefile
+	data/device/pcisig.com/pci-10ec-8029.d/Makefile
+	data/device/pcisig.com/pci-10ec-8139.d/Makefile
+	data/device/pcisig.com/pci-1234-1111.d/Makefile
+	data/device/pcisig.com/pci-1274-5000.d/Makefile
+	data/device/pcisig.com/pci-15ad-0710.d/Makefile
+	data/device/pcisig.com/pci-1af4-1000.d/Makefile
+	data/device/pcisig.com/pci-1af4-1001.d/Makefile
+	data/device/pcisig.com/pci-1af4-1002.d/Makefile
+	data/device/pcisig.com/pci-1af4-1003.d/Makefile
+	data/device/pcisig.com/pci-1af4-1009.d/Makefile
+	data/device/pcisig.com/pci-1b36-0100.d/Makefile
+	data/device/pcisig.com/pci-8086-100e.d/Makefile
+	data/device/pcisig.com/pci-8086-2415.d/Makefile
+	data/device/pcisig.com/pci-8086-25ab.d/Makefile
+	data/device/pcisig.com/pci-8086-2668.d/Makefile
 	data/device/usb.org/Makefile
+	data/device/usb.org/usb-80ee-0021.d/Makefile
 	data/device/xen.org/Makefile
 	data/platform/Makefile
 	data/platform/linux-kvm.org/Makefile
diff --git a/data/device/pcisig.com/Makefile.am b/data/device/pcisig.com/Makefile.am
index ee4552b..567618a 100644
--- a/data/device/pcisig.com/Makefile.am
+++ b/data/device/pcisig.com/Makefile.am
@@ -1 +1,23 @@
+
+SUBDIRS = \
+	pci-1000-0012.d \
+	pci-1013-00b8.d \
+	pci-1022-2000.d \
+	pci-10ec-8029.d \
+	pci-10ec-8139.d \
+	pci-1234-1111.d \
+	pci-1274-5000.d \
+	pci-15ad-0710.d \
+	pci-1af4-1000.d \
+	pci-1af4-1001.d \
+	pci-1af4-1002.d \
+	pci-1af4-1003.d \
+	pci-1af4-1009.d \
+	pci-1b36-0100.d \
+	pci-8086-100e.d \
+	pci-8086-2415.d \
+	pci-8086-25ab.d \
+	pci-8086-2668.d \
+	$(NULL)
+
 include ../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1000-0012.d/Makefile.am b/data/device/pcisig.com/pci-1000-0012.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1000-0012.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1000-0012.xml.in b/data/device/pcisig.com/pci-1000-0012.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1000-0012.xml.in
rename to data/device/pcisig.com/pci-1000-0012.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1013-00b8.d/Makefile.am b/data/device/pcisig.com/pci-1013-00b8.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1013-00b8.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1013-00b8.xml.in b/data/device/pcisig.com/pci-1013-00b8.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1013-00b8.xml.in
rename to data/device/pcisig.com/pci-1013-00b8.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1022-2000.d/Makefile.am b/data/device/pcisig.com/pci-1022-2000.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1022-2000.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1022-2000.xml.in b/data/device/pcisig.com/pci-1022-2000.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1022-2000.xml.in
rename to data/device/pcisig.com/pci-1022-2000.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-10ec-8029.d/Makefile.am b/data/device/pcisig.com/pci-10ec-8029.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-10ec-8029.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-10ec-8029.xml.in b/data/device/pcisig.com/pci-10ec-8029.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-10ec-8029.xml.in
rename to data/device/pcisig.com/pci-10ec-8029.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-10ec-8139.d/Makefile.am b/data/device/pcisig.com/pci-10ec-8139.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-10ec-8139.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-10ec-8139.xml.in b/data/device/pcisig.com/pci-10ec-8139.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-10ec-8139.xml.in
rename to data/device/pcisig.com/pci-10ec-8139.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1234-1111.d/Makefile.am b/data/device/pcisig.com/pci-1234-1111.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1234-1111.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1274-5000.d/Makefile.am b/data/device/pcisig.com/pci-1274-5000.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1274-5000.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1274-5000.xml.in b/data/device/pcisig.com/pci-1274-5000.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1274-5000.xml.in
rename to data/device/pcisig.com/pci-1274-5000.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-15ad-0710.d/Makefile.am b/data/device/pcisig.com/pci-15ad-0710.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-15ad-0710.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-15ad-0710.xml.in b/data/device/pcisig.com/pci-15ad-0710.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-15ad-0710.xml.in
rename to data/device/pcisig.com/pci-15ad-0710.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1af4-1000.d/Makefile.am b/data/device/pcisig.com/pci-1af4-1000.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1af4-1000.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1af4-1000.xml.in b/data/device/pcisig.com/pci-1af4-1000.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1af4-1000.xml.in
rename to data/device/pcisig.com/pci-1af4-1000.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1af4-1001.d/Makefile.am b/data/device/pcisig.com/pci-1af4-1001.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1af4-1001.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1af4-1001.xml.in b/data/device/pcisig.com/pci-1af4-1001.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1af4-1001.xml.in
rename to data/device/pcisig.com/pci-1af4-1001.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1af4-1002.d/Makefile.am b/data/device/pcisig.com/pci-1af4-1002.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1af4-1002.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1af4-1002.xml.in b/data/device/pcisig.com/pci-1af4-1002.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1af4-1002.xml.in
rename to data/device/pcisig.com/pci-1af4-1002.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1af4-1003.d/Makefile.am b/data/device/pcisig.com/pci-1af4-1003.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1af4-1003.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1af4-1003.xml.in b/data/device/pcisig.com/pci-1af4-1003.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1af4-1003.xml.in
rename to data/device/pcisig.com/pci-1af4-1003.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1af4-1009.d/Makefile.am b/data/device/pcisig.com/pci-1af4-1009.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1af4-1009.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1af4-1009.xml.in b/data/device/pcisig.com/pci-1af4-1009.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1af4-1009.xml.in
rename to data/device/pcisig.com/pci-1af4-1009.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-1b36-0100.d/Makefile.am b/data/device/pcisig.com/pci-1b36-0100.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-1b36-0100.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-1b36-0100.xml.in b/data/device/pcisig.com/pci-1b36-0100.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-1b36-0100.xml.in
rename to data/device/pcisig.com/pci-1b36-0100.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-8086-100e.d/Makefile.am b/data/device/pcisig.com/pci-8086-100e.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-8086-100e.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-8086-100e.xml.in b/data/device/pcisig.com/pci-8086-100e.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-8086-100e.xml.in
rename to data/device/pcisig.com/pci-8086-100e.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-8086-2415.d/Makefile.am b/data/device/pcisig.com/pci-8086-2415.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-8086-2415.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-8086-2415.xml.in b/data/device/pcisig.com/pci-8086-2415.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-8086-2415.xml.in
rename to data/device/pcisig.com/pci-8086-2415.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-8086-25ab.d/Makefile.am b/data/device/pcisig.com/pci-8086-25ab.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-8086-25ab.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-8086-25ab.xml.in b/data/device/pcisig.com/pci-8086-25ab.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-8086-25ab.xml.in
rename to data/device/pcisig.com/pci-8086-25ab.d/class.xml.in
diff --git a/data/device/pcisig.com/pci-8086-2668.d/Makefile.am b/data/device/pcisig.com/pci-8086-2668.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/pcisig.com/pci-8086-2668.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/pcisig.com/pci-8086-2668.xml.in b/data/device/pcisig.com/pci-8086-2668.d/class.xml.in
similarity index 100%
rename from data/device/pcisig.com/pci-8086-2668.xml.in
rename to data/device/pcisig.com/pci-8086-2668.d/class.xml.in
diff --git a/data/device/usb.org/Makefile.am b/data/device/usb.org/Makefile.am
index ee4552b..37a2078 100644
--- a/data/device/usb.org/Makefile.am
+++ b/data/device/usb.org/Makefile.am
@@ -1 +1,2 @@
-include ../../Makefile.inc
+
+SUBDIRS = usb-80ee-0021.d
diff --git a/data/device/usb.org/usb-80ee-0021.d/Makefile.am b/data/device/usb.org/usb-80ee-0021.d/Makefile.am
new file mode 100644
index 0000000..4ce2491
--- /dev/null
+++ b/data/device/usb.org/usb-80ee-0021.d/Makefile.am
@@ -0,0 +1 @@
+include ../../../Makefile.inc
diff --git a/data/device/usb.org/usb-80ee-0021.xml.in b/data/device/usb.org/usb-80ee-0021.d/class.xml.in
similarity index 100%
rename from data/device/usb.org/usb-80ee-0021.xml.in
rename to data/device/usb.org/usb-80ee-0021.d/class.xml.in
diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c
index 30546b4..b828291 100644
--- a/osinfo/osinfo_loader.c
+++ b/osinfo/osinfo_loader.c
@@ -74,6 +74,13 @@ struct _OsinfoEntityKey
 };
 typedef struct _OsinfoEntityKey OsinfoEntityKey;
 
+typedef struct OsinfoLoaderEntityFiles OsinfoLoaderEntityFiles;
+
+struct OsinfoLoaderEntityFiles {
+    GFile *master;
+    GList *extensions;
+};
+
 static void
 osinfo_loader_finalize(GObject *object)
 {
@@ -496,6 +503,8 @@ static gboolean osinfo_loader_check_id(const gchar *relpath,
     gchar *name;
     gchar *suffix;
     gboolean sep = FALSE;
+    gchar *reldir;
+    gboolean extension;
     gsize i;
     if (g_str_has_prefix(id, "http://")) {
         suffix = g_strdup(id + strlen("http://"));
@@ -512,18 +521,28 @@ static gboolean osinfo_loader_check_id(const gchar *relpath,
                 suffix[i] = '-';
         }
     }
-    name = g_strdup_printf("/%s/%s.xml", type, suffix);
+    reldir = g_path_get_dirname(relpath);
+    if (g_str_has_suffix(reldir, ".d")) {
+        name = g_strdup_printf("/%s/%s.d", type, suffix);
+        extension = TRUE;
+    } else {
+        name = g_strdup_printf("/%s/%s.xml", type, suffix);
+        extension = FALSE;
+    }
     g_free(suffix);
 
-    if (!g_str_equal(relpath, name)) {
+    if (!g_str_equal(extension ? reldir : relpath, name)) {
         g_warning("Entity %s should be in file %s not %s",
-                  id, name, relpath);
+                  id, name, extension ? reldir : relpath);
+        g_free(reldir);
+        g_free(name);
         return TRUE; /* In future switch to FALSE to refuse
                       * to load non-compliant named files.
                       * Need a period of grace for backcompat
                       * first though... Switch ETA Jan 2017
                       */
     }
+    g_free(reldir);
     g_free(name);
     return TRUE;
 }
@@ -1665,6 +1684,7 @@ static void osinfo_loader_process_xml(OsinfoLoader *loader,
 static void
 osinfo_loader_process_file_reg_ids(OsinfoLoader *loader,
                                    GFile *file,
+                                   GHashTable *allentries,
                                    gboolean withSubsys,
                                    const char *baseURI,
                                    const char *busType,
@@ -1749,6 +1769,15 @@ osinfo_loader_process_file_reg_ids(OsinfoLoader *loader,
 
                 gchar *id = g_strdup_printf("%s/%s/%s/%s",
                                             baseURI, busType, vendor_id, device_id);
+                gchar *key = g_strdup_printf("/device/%s/%s-%s-%s",
+                                              baseURI + 7, busType, vendor_id, device_id);
+                OsinfoLoaderEntityFiles *files = g_hash_table_lookup(allentries, key);
+                g_free(key);
+                if (files && files->master) {
+                    /* Native database has a matching entry that completely
+                     * replaces the external record */
+                    continue;
+                }
 
                 OsinfoDevice *dev = osinfo_loader_get_device(loader, id);
                 g_hash_table_remove(loader->priv->entity_refs, id);
@@ -1792,10 +1821,12 @@ osinfo_loader_process_file_reg_ids(OsinfoLoader *loader,
 static void
 osinfo_loader_process_file_reg_usb(OsinfoLoader *loader,
                                    GFile *file,
+                                   GHashTable *allentries,
                                    GError **err)
 {
     osinfo_loader_process_file_reg_ids(loader,
                                        file,
+                                       allentries,
                                        FALSE,
                                        "http://usb.org",
                                        "usb",
@@ -1805,10 +1836,12 @@ osinfo_loader_process_file_reg_usb(OsinfoLoader *loader,
 static void
 osinfo_loader_process_file_reg_pci(OsinfoLoader *loader,
                                    GFile *file,
+                                   GHashTable *allentries,
                                    GError **err)
 {
     osinfo_loader_process_file_reg_ids(loader,
                                        file,
+                                       allentries,
                                        TRUE,
                                        "http://pcisig.com",
                                        "pci",
@@ -1851,13 +1884,96 @@ osinfo_loader_process_file_reg_xml(OsinfoLoader *loader,
 }
 
 
-static GList *osinfo_loader_find_files(OsinfoLoader *loader,
-                                       GFile *file,
-                                       GError **err)
+static void osinfo_loader_entity_files_free(OsinfoLoaderEntityFiles *files)
+{
+    if (!files)
+        return;
+    g_list_foreach(files->extensions, (GFunc)g_object_unref, NULL);
+    g_list_free(files->extensions);
+    if (files->master)
+        g_object_unref(files->master);
+    g_free(files);
+}
+
+
+static void osinfo_loader_entity_files_add_path(GHashTable *entries,
+                                                GFile *base,
+                                                GFile *ent)
+{
+    /*
+     * We have paths which are either:
+     *
+     *   $DB_ROOT/os/fedoraproject.org/fedora-19.xml
+     *   $DB_ROOT/os/fedoraproject.org/fedora-19.d/fragment.xml
+     *
+     * And need to extract the prefix
+     *
+     *   os/fedoraproject.org/fedora-19
+     *
+     * We assume that no domain names end with '.d'
+     */
+    gchar *path = g_file_get_path(ent);
+    const gchar *relpath = path;
+    gchar *dirname;
+    gchar *key = NULL;
+    gboolean extension = FALSE;
+    OsinfoLoaderEntityFiles *entry;
+    gchar *basepath = g_file_get_path(base);
+
+    g_object_set_data(G_OBJECT(ent), "base", base);
+
+    if (g_str_has_prefix(path, basepath))
+        relpath += strlen(basepath);
+
+    dirname = g_path_get_dirname(relpath);
+
+    if (g_str_has_suffix(dirname, ".d")) {
+        key = g_strdup(dirname);
+        key[strlen(key) - 2] = '\0';
+        extension = TRUE;
+    } else if (g_str_has_suffix(relpath, ".xml")) {
+        key = g_strdup(relpath);
+        key[strlen(key) - 4] = '\0';
+    } else {
+        /* This should not be reached, since we already
+         * filtered to only have files in .xml
+         */
+        g_warning("Unexpected database file %s", path);
+        goto error;
+        return;
+    }
+
+    entry = g_hash_table_lookup(entries, key);
+    if (!entry) {
+        entry = g_new0(OsinfoLoaderEntityFiles, 1);
+        g_hash_table_insert(entries, g_strdup(key), entry);
+    }
+    g_object_ref(ent);
+    if (extension) {
+        entry->extensions = g_list_append(entry->extensions, ent);
+    } else {
+        if (entry->master) {
+            g_warning("Unexpected duplicate master file %s", path);
+        }
+        entry->master = ent;
+    }
+
+ error:
+    g_free(key);
+    g_free(dirname);
+    g_free(path);
+    g_free(basepath);
+}
+
+
+static void osinfo_loader_find_files(OsinfoLoader *loader,
+                                     GFile *base,
+                                     GFile *file,
+                                     GHashTable *entries,
+                                     GError **err)
 {
     GError *error = NULL;
     GFileInfo *child;
-    GList *files = NULL;
     GFileEnumerator *ents = g_file_enumerate_children(file,
                                                       "standard::*",
                                                       G_FILE_QUERY_INFO_NONE,
@@ -1879,25 +1995,19 @@ static GList *osinfo_loader_find_files(OsinfoLoader *loader,
                                                           G_FILE_ATTRIBUTE_STANDARD_TYPE);
         if (type == G_FILE_TYPE_REGULAR) {
             if (g_str_has_suffix(name, ".xml"))
-                files = g_list_append(files, g_object_ref(ent));
+                osinfo_loader_entity_files_add_path(entries, base, ent);
         } else if (type == G_FILE_TYPE_DIRECTORY) {
-            GList *subfiles = osinfo_loader_find_files(loader, ent, &error);
-            if (subfiles) {
-                files = g_list_concat(files, subfiles);
-            }
+            osinfo_loader_find_files(loader, base, ent, entries, &error);
         }
         g_object_unref(ent);
         g_object_unref(child);
 
         if (error) {
-            g_list_foreach(files, (GFunc)g_object_unref, NULL);
-            g_list_free(files);
-            return NULL;
+            break;
         }
     }
 
     g_object_unref(ents);
-    return files;
 }
 
 
@@ -1912,41 +2022,92 @@ static void osinfo_loader_process_list(OsinfoLoader *loader,
                                        GError **err)
 {
     GError *lerr = NULL;
+    GFile **tmp;
+    GHashTable *allentries = g_hash_table_new_full(g_str_hash,
+                                                   g_str_equal,
+                                                   g_free,
+                                                   (GDestroyNotify)osinfo_loader_entity_files_free);
     GHashTableIter iter;
     gpointer key, value;
 
-    while (dirs && *dirs) {
-        OsinfoLoaderDataFormat fmt = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(*dirs), "data-format"));
+    /* Phase 1: gather the files in each native format location */
+    tmp = dirs;
+    while (tmp && *tmp) {
+        OsinfoLoaderDataFormat fmt = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(*tmp), "data-format"));
 
-        switch (fmt) {
-        case OSINFO_DATA_FORMAT_NATIVE: {
-            GList *files = osinfo_loader_find_files(loader, *dirs, &lerr);
-            GList *tmp;
-            if (lerr) {
-                g_propagate_error(err, lerr);
-                return;
-            }
+        if (fmt != OSINFO_DATA_FORMAT_NATIVE) {
+            tmp++;
+            continue;
+        }
 
-            tmp = files;
-            while (tmp) {
-                osinfo_loader_process_file_reg_xml(loader, *dirs, tmp->data, &lerr);
-                if (lerr) {
-                    g_propagate_error(err, lerr);
-                    break;
-                }
-                tmp = tmp->next;
+        GHashTable *entries = g_hash_table_new_full(g_str_hash,
+                                                    g_str_equal,
+                                                    g_free,
+                                                    (GDestroyNotify)osinfo_loader_entity_files_free);
+
+        osinfo_loader_find_files(loader, *tmp, *tmp, entries, &lerr);
+        if (lerr) {
+            g_propagate_error(err, lerr);
+            return;
+        }
+
+        /* 'entries' contains a list of files from this location, which
+         * we need to merge with any previously gathered files.
+         *
+         * If 'allentries' already contains an entry with the matching key
+         *
+         *  => If 'entries' has the master file present, this completely
+         *     replaces the data in 'allentries.'
+         *  => Else we just augment the extensions in 'allentries'
+         */
+        g_hash_table_iter_init(&iter, entries);
+        while (g_hash_table_iter_next(&iter, &key, &value)) {
+            const gchar *path = key;
+            OsinfoLoaderEntityFiles *newfiles = value;
+            OsinfoLoaderEntityFiles *oldfiles;
+
+            oldfiles = g_hash_table_lookup(allentries, key);
+            if (!oldfiles || newfiles->master) {
+                /* Completely new, or replacing master */
+                oldfiles = g_new0(OsinfoLoaderEntityFiles, 1);
+                oldfiles->master = newfiles->master;
+                newfiles->master = NULL;
+                oldfiles->extensions = newfiles->extensions;
+                newfiles->extensions = NULL;
+                g_hash_table_insert(allentries, g_strdup(path), oldfiles);
+            } else {
+                /* Just augmenting the extensions */
+                oldfiles->extensions = g_list_concat(oldfiles->extensions,
+                                                     newfiles->extensions);
+                newfiles->extensions = NULL;
             }
-            g_list_foreach(files, (GFunc)g_object_unref, NULL);
-            g_list_free(files);
+        }
+
+        g_hash_table_unref(entries);
 
-        }   break;
+        tmp++;
+    }
+
+    if (lerr)
+        return;
+
+    /* Phase 2: load data from non-native locations, filtering based
+     * on overrides from native locations */
+    tmp = dirs;
+    while (tmp && *tmp) {
+        OsinfoLoaderDataFormat fmt = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(*tmp), "data-format"));
+
+        switch (fmt) {
+        case OSINFO_DATA_FORMAT_NATIVE:
+            /* nada */
+            break;
 
         case OSINFO_DATA_FORMAT_PCI_IDS:
-            osinfo_loader_process_file_reg_pci(loader, *dirs, &lerr);
+            osinfo_loader_process_file_reg_pci(loader, *tmp, allentries, &lerr);
             break;
 
         case OSINFO_DATA_FORMAT_USB_IDS:
-            osinfo_loader_process_file_reg_usb(loader, *dirs, &lerr);
+            osinfo_loader_process_file_reg_usb(loader, *tmp, allentries, &lerr);
             break;
         }
 
@@ -1954,9 +2115,44 @@ static void osinfo_loader_process_list(OsinfoLoader *loader,
             break;
         }
 
-        dirs++;
+        tmp++;
+    }
+
+    if (lerr)
+        return;
+
+    /* Phase 3: load combined set of files from native locations */
+    g_hash_table_iter_init(&iter, allentries);
+    while (g_hash_table_iter_next(&iter, &key, &value)) {
+        OsinfoLoaderEntityFiles *files = value;
+        GList *tmpl;
+        if (files->master) {
+            osinfo_loader_process_file_reg_xml(loader,
+                                               g_object_get_data(G_OBJECT(files->master), "base"),
+                                               files->master, &lerr);
+            if (lerr) {
+                g_propagate_error(err, lerr);
+                break;
+            }
+        }
+
+        tmpl = files->extensions;
+        while (tmpl) {
+            GFile *file = tmpl->data;
+            osinfo_loader_process_file_reg_xml(loader,
+                                               g_object_get_data(G_OBJECT(file), "base"),
+                                               file,
+                                               &lerr);
+            if (lerr) {
+                g_propagate_error(err, lerr);
+                break;
+            }
+
+            tmpl = tmpl->next;
+        }
     }
 
+    g_hash_table_unref(allentries);
     g_hash_table_iter_init(&iter, loader->priv->entity_refs);
     while (g_hash_table_iter_next(&iter, &key, &value)) {
         g_warning("Entity %s referenced but not defined", (const char *)key);
-- 
2.4.3




More information about the Libosinfo mailing list