summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Dennis <jdennis@redhat.com>2013-03-22 17:01:12 -0400
committerJohn Dennis <jdennis@redhat.com>2013-03-22 17:01:12 -0400
commitb6e01f4262176376920a59038012a4ef273d0235 (patch)
tree5fa2aa8e6bf0d7df3a921b05a77bb1c1a17670ad
parent52a346870008e04518984a64d3b1bf44534f7f5e (diff)
downloadrealmd-cim-b6e01f4262176376920a59038012a4ef273d0235.tar.gz
realmd-cim-b6e01f4262176376920a59038012a4ef273d0235.tar.xz
realmd-cim-b6e01f4262176376920a59038012a4ef273d0235.zip
Update README with useful information for developers
-rw-r--r--CMakeLists.txt2
-rw-r--r--README212
2 files changed, 210 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ca18b41..6be16c7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,7 +25,7 @@ set(provider_SRCS
rdcp_util.c
)
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -DRDCP_DEBUG")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
konkretcmpi_generate(${MOF}
CIM_PROVIDERS
diff --git a/README b/README
index 2c32d89..dec6866 100644
--- a/README
+++ b/README
@@ -1,15 +1,221 @@
Realmd CIM Provider
+Building
+========
+
+Prerequisites:
+--------------
+
+To build you'll need these packages installed:
+
+cmake
+openlmi-providers-devel
+konkretcmpi
+
+
+To install and run you'll need at a minimum:
+--------------------------------------------
+
+tog-pegasus
+openlmi-providers
+
+
+This project uses the same build mechanism as openlmi-provider which
+is based on cmake. It's also important specify the same cmake
+configuration parameters enforced by RPM.
+
+My short term solution is to use the following shell script. I add the
+CFLAGS override to turn on options useful for debugging during
+development, you may wish to omit that.
+
+<<<<<<<<<<
+#!/bin/sh
+
+export CFLAGS='-g -O0 -DRDCP_DEBUG'
+
+/usr/bin/cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr -DINCLUDE_INSTALL_DIR:PATH=/usr/include -DLIB_INSTALL_DIR:PATH=/usr/lib -DSYSCONF_INSTALL_DIR:PATH=/etc -DSHARE_INSTALL_PREFIX:PATH=/usr/share -DBUILD_SHARED_LIBS:BOOL=ON .
+
+if [ $? -eq 0 ]; then
+ make
+fi
+>>>>>>>>>>
+
+Installing:
+-----------
+
+% sudo make install
+
+This copies the mof file, the registration file and the loadable
+module to their destination. Then you must register your module with
+the Pegasus CIMOM. Note: pegasus MUST be running!
+
+% openlmi-mof-register register /usr/share/openlmi-providers/LMI_Realmd.mof /usr/share/openlmi-providers/LMI_Realmd.reg
+
+Development Tips:
+-----------------
+
+Understanding konkret code generation issues:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+konkret is a tool that reads in a mof file and generates C code. For
+every XXX class it will generate a XXX.h and XXXProvider.c file. The
+code generation occurs due to CMake macros provided by the
+openlmi-providers-devel package. konkret needs to run any time you
+modify the mof file. It *always* generates a new XXX.h file because
+that's where definitions based on the contents of the mof file are
+located. If there is no XXXProvider.c file it will also generate
+it. This is a "stub" file in which you will fill in with your
+implementation. If XXXProvider.c exits it will not overwrite it,
+however it always overwrites the XXX.h file.
+
+Do not put anything into the XXX.h file you'll need to retain.
+
+After editing the mof file the make targets will cause konkret to run
+again. You'll get brand new XXX.h files. But your old XXXProvider.c
+files may no longer have the correct definitions (e.g. prototypes)
+found in the XXX.h file so you may need to hand edit by copying the
+function prototype from the XXX.h file into your XXXProvider.c file.
+
+If you've written definitions that logically belong in XXX.h but don't
+want them nuked the next time konkret runs my solution was to put them
+in someother .h file that's included by the XXXProvider.c file.
+
+Initializing class instances:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The way konkret works is to emit specialized inline functions to
+initialize each member of a class. If the class is subclassed you get
+different initializers depending on whether the property is in the
+parent class or the subclass. You cannot call a parent class property
+initializer in a subclass (yuck), you have to use the subclass
+initializer for the property inherited from the parent class. This
+creates a maintenance problem if the parent class changes, you have
+find every place parent class properties are inialized and make
+changes. To solve this problem I defined macros that initialize class
+properties. The macro takes a "klass" parameter and token pastes it to
+generate the class specific property manipulation function call. Using
+these macros means anytime a class changes due to a change in the mof
+file there is only one place where you need to change the code. These
+macros are a good example of what logically belongs in the XXX.h file
+but are separated out into a different .h file because konkret will
+nuke anything you've added to a XXX.h file.
+
+Modifications to the provider:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+During development if the mof file changes you have to make Pegasus
+reload the mof. It's not sufficient to retart cimserver, you have to
+unregister the provider and register it again for Pegasus to see the
+mof changes. Thus you would use the openlmi-mof-register command above
+except pass the unregister option, followed by the above command, e.g.
+
+% openlmi-mof-register unregister /usr/share/openlmi-providers/LMI_Realmd.mof /usr/share/openlmi-providers/LMI_Realmd.reg
+% openlmi-mof-register register /usr/share/openlmi-providers/LMI_Realmd.mof /usr/share/openlmi-providers/LMI_Realmd.reg
+
+If all you've done during devopment is modify the provider (not it's
+mof definition) then all you need to do is:
+
+% sudo cimserver -s
+% sudo make install
+% sudo cimserver
+
+How do I run the Pegasus CIMOM so I can see debug statements?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+% sudo cimserver daemon=false forceProviderProcesses=false
+
+How do I use GDB to debug my provider?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Create the following .gdbinit file where XXX is where you want to break.
+
+<<<<<<<<<<
+set breakpoint pending on
+b XXX
+r daemon=false forceProviderProcesses=false
+>>>>>>>>>>
+
+then run gdb like this:
+
+% sudo gdb cimserver
+
+How do I trace what Pegasus is doing?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+% cimserver daemon=false forceProviderProcesses=false logLevel=TRACE traceLevel=5 traceFacility=File traceComponents=All
+
+The trace file is written to:
+
+/var/lib/Pegasus/cache/trace/cimserver.trc
+
+More information about cimserver tracing can be found in the
+"OpenPegasus Tracing User Guide" PDF. Google the title to get a
+current URL.
+
FAQ
----
+===
Q: What does the rdcp acronym stand for?
A: Realmd CIM Provider. The "rd" is for Realmd, the "c" is for CIM and
the "p" is for Provider
+Q: What decisions influenced your DBus implementation strategy?
+
+A: There are essentially two supported DBus API's. A very high level
+ GDBus and a very low level libdbus.
+
+ GDBus requires you to utilize Gnome's GObject pseudo
+ object-orientated framework. If you're not familar with it it's a
+ fairly steep learning curve to become proficient. Also if you're
+ not proficient in GObject programming it's hard to comprehend code
+ which utilizes it thus putting normal C developers at a
+ disadvantage. However GDBus gives you a lot of nice support, one of
+ the nice features is everything is based on GVariants, a powerful
+ data structure.
+
+ On the other hand libdbus is very low level, there is very little
+ support for the necessary DBus operations. However it is used
+ extensively by other projects so it's not an aberration to use it,
+ it's pure C code making it easier to understand and it doesn't pull
+ in the whole GObject system. But it's a lot of work to use.
+
+ I took a compromise approach. I didn't have the time to become
+ proficient with GObject and I felt the GObject based code was
+ difficult for C programmers without GObject experience to read
+ and modify. However I recognized the value of expressing most
+ things in terms of GVariants, a hallmark of GDBus. So I wrote some
+ utility code that supports serializing GVariants into and out of
+ libdbus. This allowed me to use the powerful GVariant without
+ having to get involved with GObjects and GDBus. If we ever decide
+ to port the code to GDBus it shold be fairly straight forward
+ because we're already using GVariant's as a fundamental type. This
+ seemed to represent a reasonable compromise between libdus and
+ GDBus, it avoids the pseudo object-orientated framework of GObject
+ in favor of vanilla C code but retains the powerful use of
+ GVariants. I guess only time will tell if it was a smart choice or
+ not.
ToDo
-----
+====
+
+Implement locale in RealmdService.
+
+Utilize CMPI Logging instead of debug printf statements (currently
+controlled by the RDCP_DEBUG compile time flag).
+
+Generate indications when realms are added or removed from the Realms
+property of the LMI_RealmdService.
+
+Any blocking operations should not block the CIMOM.
+(e.g. communicating with DBus). I think the right way to do this is
+via the CMPI threading support, but this needs further
+investigation. Other openlmi developers would be a good resource for
+this issue.
-Implement locale in RealmdService
+We call DBus to get object properties a lot. There is I believe
+support for DBus clients which caches object properties and listens on
+the properties change signal to refresh the properties cache. Access
+to the properties are then performed via the local properties cache
+rather than the via RPC. Obviously this is much more efficient, we
+should support it.