pmda(3)

NAME

   PMDA  -  introduction  to  the Performance Metrics Domain Agent support
   library

C SYNOPSIS

   #include <pcp/pmapi.h>
   #include <pcp/impl.h>
   #include <pcp/pmda.h>

   cc ... -lpcp_pmda -lpcp

DESCRIPTION

   To assist in  the  development  of  Performance  Metric  Domain  Agents
   (PMDAs)  for  the Performance Co-Pilot (PCP), a procedural interface is
   provided that extends the Performance Metrics  Application  Programming
   Interface ( PMAPI(3)) library.  These procedures are designed to enable
   a programmer to quickly build a PMDA  which  can  then  be  tested  and
   refined.   However,  this  also  implies  that  a PMDA has a particular
   structure which may not be suitable for all PMDA implementations.

   Once you are familiar with the PCP and PMDA frameworks, you can quickly
   implement  a  new  PMDA  with only a few data structures and functions.
   This is covered in far  greater  detail  in  the  Performance  Co-Pilot
   Programmer's Guide.

   A  PMDA  is  responsible for a set of performance metrics, in the sense
   that it must respond to requests from  pmcd(1)  for  information  about
   performance metrics, instance domains, and instantiated values.

   This  man page contains sections of the simple PMDA which is located at
   $PCP_PMDAS_DIR/simple.

COMMUNICATING WITH PMCD

   Two approaches may be used for connecting a PMDA to a pmcd(1)  process.
   A  Dynamic  Shared  Object  (DSO)  can  be  attached  by  pmcd(1) using
   dlopen(3) when the pmcd(1) process is started.  A procedural  interface
   referenced  through  a shared data structure is used to handle requests
   from pmcd(1) to the PMDA .

   The  preferred  approach  is  for  a  separate  process   (daemon)   to
   communicate  with pmcd(1) using the Performance Data Units (PDU) Inter-
   Process Communication (IPC) protocol.

   All PMDAs are launched and controlled by the  pmcd(1)  process  on  the
   local  host.  The requests from the clients are received by pmcd(1) and
   forwarded to the appropriate  PMDAs.   Responses,  when  required,  are
   returned  through pmcd(1) to the clients.  The requests (PDUs) that may
   be  sent  to  a  PMDA  from   pmcd(1)   are   PDU_FETCH,   PDU_PROFILE,
   PDU_INSTANCE_REQ,  PDU_DESC_REQ,  PDU_TEXT_REQ  and PDU_RESULT.  If the
   PMDA implements any dynamic metrics it may also receive PDU_PMNS_CHILD,
   PDU_PMNS_IDS, PDU_PMNS_NAMES and PDU_PMNS_TRAVERSE PDUs.

DEFAULT CALLBACKS FOR HANDLING PDUs

   To  allow  a  consistent framework, pmdaMain(3) can be used by a daemon
   PMDA to handle the communication protocol using the same callbacks as a
   DSO  PMDA.   The  structure  pmdaInterface is used to convey the common
   procedural interface and state information that is used by pmcd(1)  and
   a   PMDA.   This  state  information  includes  tables  describing  the
   supported metrics and instance domains.

   As most of the procedural interface is identical for  all  PMDAs,  they
   are   provided   as  part  of  this  support  library  (pmdaProfile(3),
   pmdaFetch(3),    pmdaInstance(3),    pmdaDesc(3),    pmdaText(3)    and
   pmdaStore(3)).    However,   these   routines  require  access  to  the
   pmdaInterface state information so it  must  be  correctly  initialized
   using   pmdaConnect(3),   pmdaDaemon(3),   pmdaOpenLog(3),  pmdaDSO(3),
   pmdaGetOpt(3) and pmdaInit(3).

INSTANCES AND INSTANCE DOMAINS

   Three structures are declared in /usr/include/pcp/pmda.h which  provide
   a  framework  for  declaring the metrics and instances supported by the
   PMDA.

   Every instance requires a unique integer identifier and a unique  name,
   as defined by the structure pmdaInstid:

        /*
         * Instance description: index and name
         */

        typedef struct {
            int         i_inst;        /* internal instance identifier */
            char        *i_name;       /* external instance identifier */
        } pmdaInstid;

   An  instance  domain  requires its own unique identification (pmInDom),
   the number of instances the domain represents,  and  a  pointer  to  an
   array  of  instance  descriptions.   This  is  defined in the structure
   pmdaIndom:

        /*
         * Instance domain description: unique instance id,
         * number of instances in this domain, and the list of
         * instances (not null terminated).
         */

        typedef struct {
            pmInDom     it_indom;       /* indom, filled in */
            int         it_numinst;     /* number of instances */
            pmdaInstid  *it_set;        /* instance identifiers */
        } pmdaIndom;

   The simple PMDA has one instance domain  for  simple.color  with  three
   instances  (red,  green  and  blue),  and  a second instance domain for
   simple.now with instances which can be specified  at  run-time.   These
   instance domains are defined as:

        static pmdaInstid _color[] = {
            { 0, "red" }, { 1, "green" }, { 2, "blue" }
        };
        static pmdaInstid *_timenow = NULL;

        static pmdaIndom indomtab[] = {
        #define COLOR_INDOM 0
            { COLOR_INDOM, 3, _color },
        #define NOW_INDOM 1
            { NOW_INDOM, 0, NULL },
        };

   The  preprocessor  macros  COLOR_INDOM  and  NOW_INDOM  are used in the
   metric description table to identify the instance domains of individual
   metrics.   These  correspond to the serial value in the instance domain
   pmInDom structure (the domain field is set by pmdaInit(3) at run-time).
   The  serial  value  must  be unique for each instance domain within the
   PMDA.

   The indom table shown above which is usually passed to pmdaInit(3) does
   not  need  to  be  created  if  one  wants to write one's own Fetch and
   Instance functions.  See pmdaInit(3) for more details.

NAMESPACE

   Every PMDA has its own unique namespace using  the  format  defined  in
   pmns(5).  In summary, the namespace matches the names of the metrics to
   the  unique  identifier.   The  simple  PMDA  defines   five   metrics:
   simple.numfetch,  simple.color,  simple.time.user,  simple.time.sys and
   simple.now.   The  namespace  for   these   metrics   is   defined   in
   $PCP_PMDAS_DIR/simple/pmns and is installed as:

        simple {
            numfetch    253:0:0
            color       253:0:1
            time
            now         253:2:4
        }

        simple.time {
            user        253:1:2
            sys         253:1:3
        }

   The  domain  number  of 253 is obtained from $PCP_VAR_DIR/pmns/stdpmid.
   New PMDAs should specify a unique  domain  number  in  this  file,  and
   obtain  the  number during installation.  This allows the domain number
   to change by modifying only the file $PCP_VAR_DIR/pmns/stdpmid.

   The simple.time and simple.now metrics are defined in separate clusters
   to  the  other  metrics  which  allows a PMDA to support more than 1024
   metrics, as well as grouping similar metrics together.  Therefore,  the
   item  numbers for a new cluster may be identical to the item numbers in
   other clusters.  The  simple  PMDA  continues  to  increment  the  item
   numbers to permit direct mapping (see pmdaInit(3)).

   The namespace file should be installed and removed with the agent using
   pmnsadd(1) and pmnsdel(1).  See the later sections on INSTALLATION  and
   REMOVAL.

   A  simple ASCII namespace can be constructed by creating a file similar
   to $PCP_PMDAS_DIR/simple/root:

        /*
         * fake "root" for validating the local PMNS subtree
         */

        #include "$PCP_VAR_DIR/pmns/stdpmid"

        root { simple }

        #include "pmns"

   and can be referred to with the -n option in most PCP tools.

METRIC DESCRIPTIONS

   Each  metric  requires  a  description  (pmDesc),  which  contains  its
   Performance Metric Identifier (PMID), data type specification, instance
   domain, semantics and units (see pmLookupDesc(3)).  A  handle  is  also
   provided   for  application  specific  information  in  the  pmdaMetric
   structure:

        /*
         * Metric description: handle for extending description,
         * and the description.
         */

        typedef struct {
            void*       m_user;         /* for users external use */
            pmDesc      m_desc;         /* metric description */
        } pmdaMetric;

   The simple PMDA defines the metrics as:

        static pmdaMetric metrictab[] = {
        /* numfetch */
            { (void *)0,
              { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
                { 0,0,0,0,0,0} }, },
        /* color */
            { (void *)0,
              { PMDA_PMID(0,1), PM_TYPE_32, COLOR_INDOM, PM_SEM_INSTANT,
                { 0,0,0,0,0,0} }, },
        /* time.user */
            { (void*)0,
              { PMDA_PMID(1,2), PM_TYPE_DOUBLE, PM_INDOM_NULL, PM_SEM_COUNTER,
                  { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
        /* time.sys */
            { (void*)0,
              { PMDA_PMID(1,3), PM_TYPE_DOUBLE, PM_INDOM_NULL, PM_SEM_COUNTER,
                  { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
        /* now */
            { NULL,
              { PMDA_PMID(2,4), PM_TYPE_U32, NOW_INDOM, PM_SEM_INSTANT,
                { 0,0,0,0,0,0 } }, },
        };

   The macro PMDA_PMID (defined in  /usr/include/pcp/pmda.h)  is  used  to
   specify  each  metric's  cluster  and  unit  number  in  the __pmID_int
   structure  defined  in  /usr/include/pcp/impl.h.   As   with   instance
   domains,  the  domain field is set by pmdaInit(3) at run-time, however,
   the default domain is assumed to be defined by the PMDA  in  the  macro
   MYDOMAIN.

   The  metric  table  shown  above which is usually passed to pmdaInit(3)
   does not need to be created if one wants to write one's own  Fetch  and
   Descriptor functions.  See pmdaInit(3) for more details.

DSO PMDA

   A  PMDA  that  is  run  as  a  DSO is opened by pmcd(1) with dlopen(3).
   pmcd(1) will call the PMDA's initialization function that is  specified
   in  $PCP_PMCDCONF_PATH.   This  function  is  passed  a  pointer  to  a
   pmdaInterface structure which must be completed.  Any  callbacks  which
   are not the default PMDA support library callbacks must be specified in
   the pmdaInterface structure.

   The simple PMDA uses its own store and fetch callback.   simple_fetch()
   calls   pmdaFetch(3)   which   requires  a  callback  to  be  set  with
   pmdaSetFetchCallBack(3)       as       can       be       seen       in
   $PCP_PMDAS_DIR/simple/simple.c.

   The  flag  _isDSO is used to determine if the PMDA is a daemon or a DSO
   so  that  the  correct   initialization   routine,   pmdaDaemon(3)   or
   pmdaDSO(3), is called.

DAEMON PMDA

   A  PMDA  that  is  run  as  a daemon is forked and executed by pmcd(1).
   Therefore, unlike a DSO PMDA, the starting point for a daemon  PMDA  is
   main().   The  agent  should parse the command line arguments, create a
   log file  and  initialize  some  data  structures  that  pmcd(1)  would
   initialize for a DSO agent.

   The  pmdaInterface  structure  must be completely defined by the daemon
   PMDA.  The function pmdaDaemon(3) can be called at the start of  main()
   to set most of these fields.  Command line parsing can be simplified by
   using pmdaGetOpt(3), which is similar  to  getopt(2),  but  extracts  a
   common  set of options into the pmdaInterface structure.  stderr can be
   mapped to a log file using pmdaOpenLog(3)  to  simplify  debugging  and
   error   messages.    The   connection  to  pmcd(1)  can  be  made  with
   pmdaConnect(3)  and  the  loop  which  handles   the   incoming   PDUs,
   pmdaMain(3),  should  be the last function called.  This can be seen in
   $PCP_PMDAS_DIR/simple/simple.c.

   The simple_init() routine is common to an agent that can be run as both
   a Daemon and DSO PMDA.

HELP TEXT

   Each  PMDA  must be able to provide pmcd(1) with the help text for each
   metric.  Most PMDAs use specially created files with indexes to support
   efficient  retrieval  of the help text.  Tools are provided with PCP to
   create the help text files of appropriate format. See newhelp(1).

INSTALLATION AND REMOVAL

   A     series     of     shell     procedures     are     defined     in
   $PCP_SHARE_DIR/lib/pmdaproc.sh  which greatly simplify the installation
   and removal of a PMDA.

   The Install scripts for most PMDAs should only need to specify the name
   of  the  PMDA  in  iam,  call  pmdaSetup  which  sets  up  some default
   variables, checks permissions (you have to be ``root''  to  install  or
   remove  a  PMDA),  checks that you're in the right directory (somewhere
   that  ends  with  /pmdas/$iam),  optionally  generate  the  Performance
   Metrics  Name  Space  (PMNS)  and  PMDA domain number files for Perl or
   Python PMDAs, checks the PMDA domain number is valid, etc., specify the
   communication  protocols,  and  finally  call pmdaInstall to do all the
   work of updating the PMNS, updating the pmcd(1) control file, notifying
   or restarting pmcd(1),

   Beyond  pmdaSetup  and pmdaInstall, another optional helper routines is
   pmdaChooseConfigFile that may be used to interactively select or create
   a PMDA-specific configuration file, e.g. pmdalogger(1).

   The  Remove  scripts  are  even simpler as setting up the communication
   protocols are not required, so set the name of the PMDA  in  iam,  then
   call pmdaSetup followed by a call to pmdaRemove.

   Further  information is contained in the $PCP_SHARE_DIR/lib/pmdaproc.sh
   file and the following section.

INSTALLATION REFINEMENTS

   As outlined below there are a number of variables that can be set in  a
   PMDA's  Install  script  to influence the behaviour of the installation
   procedures.  These would typically need to be set before  the  call  to
   pmdaInstall,   but   in   some  instances  (like  $iam  and  the  cases
   specifically noted below), before the call to pmdaSetup.

   The following variables control the communication options  between  the
   PMDA  and pmcd(1).  At least one of $daemon_opt, $dso_opt, $perl_opt or
   $python_opt  must  be  set  to  define   the   supported   mode(s)   of
   communication.   If  more  than  one  of  these is set the user will be
   prompted to make a selection when the Install script is run.

   daemon_opt      We are willing to install the PMDA as a daemon.
                   Default: true

   dso_opt         We are willing to install the PMDA as a DSO, so pmcd(1)
                   will  use  the  dynamic  linking  loader  to attach the
                   PMDA's DSO at run-time and communication  from  pmcd(1)
                   to  the  PMDA and back uses procedure calls, not an IPC
                   channel.
                   Default: false

   dso_entry       For a  DSO  PMDA,  this  is  the  name  of  the  PMDA's
                   initialization routine.
                   Default: ${iam}_init

   dso_name        For a DSO PMDA, this is the full pathanme of the PMDA's
                   DSO file.
                   Default: $PCP_PMDAS_DIR/$iam/pmda_$iam.$dso_suffix

   pipe_opt        For a daemon PMDA, is the default  IPC  channel  via  a
                   pipe(2)?
                   Default: Platform-specific, so true for most, but false
                   for Windows

   perl_opt        We are willing to install the PMDA as a Perl script and
                   pmcd(1)  will  use  the  perl(1) interpreter to run the
                   PMDA.
                   Default: false

   pmda_dir        Full  pathname  to  the  directory  where  the   PMDA's
                   installation  files  (executable,  script, PMNS source,
                   help text source, etc) are to be found.
                   Default: output from pwd(1)

                   If set, must be done before the call to pmdaSetup.

   pmda_name       For a daemon PMDA, this  is  the  name  of  the  PMDA's
                   executable binary relative to the $pmda_dir directory.
                   Default: pmda$iam

   python_opt      We  are  willing to install the PMDA as a Python script
                   and pmcd(1) will use the python(1) interpreter  to  run
                   the PMDA.
                   Default: false

   pmda_interface  There  are  multiple versions of the interface protocol
                   between a PMDA and the  libpcp_pmda  library.   If  the
                   PMDA  is built to be installed as a daemon or a DSO, it
                   will included a call to  pmdaDaemon(3)  or  pmdaDSO(3),
                   and  the  interface  argument  there will be one of the
                   PMDA_INTERFACE macros  from  <pcp/pmda.h>.   The  value
                   that   is   used  there  should  match  the  value  for
                   pmda_interface.   The  value  is  only  used   in   the
                   installation  procedure to determine the format of help
                   text to be generated by newhelp(1) and in this  context
                   all   values  of  pmda_interface  greater  than  1  are
                   equivalent (the format changed between PMDA_INTERFACE_1
                   and PMDA_INTERFACE_2).
                   Default: 3

   socket_inet_def For  a daemon PMDA using a socket(2) as the IPC channel
                   the default Internet port number or  service  name  (if
                   known).
                   Default: ""

   socket_opt      For  a  daemon  PMDA,  is the default IPC channel via a
                   socket(2)?
                   Default: Platform-specific, so false for most, but true
                   for Windows

   The following variables control the PMNS options.

   pmns_dupok      Most  PMDAs  do  not  have duplicate names for the same
                   PMID in their PMNS.  But  if  this  is  not  the  case,
                   pmns_dupok should be set to true.
                   Default: false

   pmns_name       Each  PMDA  will  add one or more non-leaf nodes to the
                   top of the PMNS.  The most common case is that  all  of
                   the  metrics  for  a PMDA will be placed below the node
                   named $iam.  If this is not the  case,  and  especially
                   when  the  PMDA adds more than one non-leaf node at the
                   top of the PMNS, pmns_name needs to be set to the  list
                   of  node  names  (separated  by  white space), e.g. for
                   pmdaproc(1) pmns_name is set to "proc cgroup hotproc".
                   Default: $iam

                   It is most important that if pmns_name is set to a non-
                   default  value  in the Install script then it must also
                   be set to the same value in the Remove script.

   pmns_source     The name of the PMDA's PMNS source file.   By  default,
                   the name is interpreted as a relative pathname from the
                   $pmda_dir directory.
                   Default: pmns

   The following variables provide assorted additional options  associated
   with the installation of a PMDA.

   args            Additional  command line args for the PMDA.  These will
                   be   appended   to   the   PMDA's   control   line   in
                   $PCP_PMCDCONF_PATH.
                   Default: ""

   check_delay     Delay   (in   seconds)   after   finishing   the   PMDA
                   installation   (or   removal)   before   checking   the
                   availability  of metrics from the PMDA.  May need to be
                   increased if the PMDA has a lengthy startup procedure.
                   Default: 0.3

   signal_delay    Delay (in  seconds)  after  notifying  pmcd(1)  with  a
                   signal.    Required   to   allow  pmcd(1)  to  complete
                   processing before proceeding to the next  step  of  the
                   installation (or removal).
                   Default: 1

   configdir       Determines    the   directory   in   which   a   PMDA's
                   configuration   file   will   be   stored.    Used   by
                   pmdaChooseConfigFile  so  should  be set before calling
                   that procedure.
                   Default: $PCP_VAR_DIR/config/$iam

   configfile      Preferred configuration file for  the  PMDA.   Used  by
                   pmdaChooseConfigFile  so  should  be set before calling
                   that procedure.
                   Default: ""

   default_configfile
                   Default configuration  file  for  the  PMDA.   Used  by
                   pmdaChooseConfigFile  so  should  be set before calling
                   that procedure.
                   Default: ""

   dso_suffix      Standard suffix for a  DSO.   Should  not  need  to  be
                   changed under normal circumstances.
                   Default:  Platform-specific, so 'so' for Linux, 'dylib'
                   for Mac OS X, 'dll' for Windows, etc.

                   If set, must be done before the call to pmdaSetup.

   help_source     The name of the help text source file  that  should  be
                   used as input to pmnewhelp(1).  By default, the name is
                   interpreted as a relative pathname from  the  $pmda_dir
                   directory.
                   Default: help

   python_name     Full pathname of the Python script for a Python PMDA.
                   Default:          $pmda_dir/pmda$iam.python          or
                   $pmda_dir/pmda$iam.py

   The shell procedures  in  $PCP_SHARE_DIR/lib/pmdaproc.sh  manipulate  a
   number of temporary files using the variable $tmp as the prefix for the
   name of the temporary files.  $tmp is a directory that is created, used
   and     removed     internally     within     the     procedures     of
   $PCP_SHARE_DIR/lib/pmdaproc.sh but can also be used as the  prefix  for
   temporary  files  needed  by  a PMDA's Install or Remove scripts.  When
   used in this way, $tmp should be followed by a ``/'' and then a suffix,
   e.g.  $tmp/myfoo.   The Install and Remove scripts should not use other
   temporary file name prefixes nor use sh(1) trap statements to clean  up
   temporary      files     as     this     is     all     done     within
   $PCP_SHARE_DIR/lib/pmdaproc.sh.

DIAGNOSTICS

   Any PMDA which  uses  this  library  can  set  PMAPI(3)  debug  control
   variable  pmDebug (with -D on the command line) to DBG_TRACE_LIBPMDA to
   enable the display of debugging information which may be useful  during
   development (see pmdbg(1)).

   The  status  field  of the pmdaInterface structure should be zero after
   pmdaDaemon, pmdaDSO, pmdaGetOpt, pmdaConnect and pmdaInit  are  called.
   A value less than zero indicates that initialization has failed.

   Some  error  messages that are common to most functions in this library
   are:

   PMDA interface version interface not supported
                  Most of the  functions  require  that  the  comm.version
                  field   of   the   pmdaInterface  structure  be  set  to
                  PMDA_INTERFACE_2   or   later.    PMDA_INTERFACE_2    or
                  PMDA_INTERFACE_3 implies that the version.two fields are
                  correctly initialized,  while  PMDA_INTERFACE_4  implies
                  that  the  version.four fields are correctly initialized
                  (see pmdaDaemon(3) and pmdaDSO(3)).

CAVEAT

   Failing to complete any of the data structures or calling  any  of  the
   library  routines  out  of  order  may cause unexpected behavior in the
   PMDA.

   Due to changes to the PMAPI(3) and PMDA(3) API in the PCP 2.0  release,
   as  described  in  the product release notes, PMDAs built using PCP 2.0
   must specify PMDA_INTERFACE_2 or later and link  with  libpcp_pmda.so.2
   and  libpcp.so.2.  Pre-existing Daemon PMDAs specifying PMDA_PROTOCOL_1
   will   continue   to   function   using   the   backwards    compatible
   libpcp_pmda.so.1  and libpcp.so.1 libraries and may be recompiled using
   the headers installed in /usr/include/pcp1.x/ without any modification.
   These  backwards  compatible headers and libraries are contained in the
   pcp.sw.compat subsystem.

FILES

   /usr/include/pcp/pmda.h
             Header file for the PMDA support library.

   /usr/lib/libpcp_pmda.so
             Dynamic library containing PMDA support library routines.

   $PCP_PMDAS_DIR/trivial
             The source of the trivial PMDA.

   $PCP_PMDAS_DIR/simple
             The source of the simple PMDA.

   $PCP_PMDAS_DIR/txmon
             The source of the txmon PMDA.

   $PCP_PMCDCONF_PATH
             Configuration file for pmcd(1).

   $PCP_VAR_DIR/pmns
             Location of namespace descriptions for every PMDA.

   $PCP_VAR_DIR/pmns/stdpmid
             The unique domain identifiers for each PMDA.

   $PCP_SHARE_DIR/lib/pmdaproc.sh
             Shell procedures for installing and removing a PMDA.

PCP ENVIRONMENT

   Environment variables with the prefix PCP_ are used to parameterize the
   file  and  directory names used by PCP.  On each installation, the file
   /etc/pcp.conf contains the  local  values  for  these  variables.   The
   $PCP_CONF  variable may be used to specify an alternative configuration
   file, as described in pcp.conf(5).  Values for these variables  may  be
   obtained programmatically using the pmGetConfig(3) function.

SEE ALSO

   dbpmda(1),   newhelp(1),  pmcd(1),  pmnsadd(1),  pmnsdel(1),  PMAPI(3),
   pmdaConnect(3), pmdaDaemon(3), pmdaDesc(3),  pmdaDSO(3),  pmdaFetch(3),
   pmdaGetOpt(3),      pmdaInit(3),      pmdaInstance(3),     pmdaMain(3),
   pmdaOpenLog(3),     pmdaProfile(3),     pmdaStore(3),      pmdaText(3),
   pmLookupDesc(3) and pmns(5).

   For  a  complete  description  of  the  pcp_pmda  library  and the PMDA
   development process, refer to the  Insight  book  Performance  Co-Pilot
   Programmer's Guide.



Opportunity


Personal Opportunity - Free software gives you access to billions of dollars of software at no cost. Use this software for your business, personal use or to develop a profitable skill. Access to source code provides access to a level of capabilities/information that companies protect though copyrights. Open source is a core component of the Internet and it is available to you. Leverage the billions of dollars in resources and capabilities to build a career, establish a business or change the world. The potential is endless for those who understand the opportunity.

Business Opportunity - Goldman Sachs, IBM and countless large corporations are leveraging open source to reduce costs, develop products and increase their bottom lines. Learn what these companies know about open source and how open source can give you the advantage.


Free Software


Free Software provides computer programs and capabilities at no cost but more importantly, it provides the freedom to run, edit, contribute to, and share the software. The importance of free software is a matter of access, not price. Software at no cost is a benefit but ownership rights to the software and source code is far more significant.

Free Office Software - The Libre Office suite provides top desktop productivity tools for free. This includes, a word processor, spreadsheet, presentation engine, drawing and flowcharting, database and math applications. Libre Office is available for Linux or Windows.


Free Books


The Free Books Library is a collection of thousands of the most popular public domain books in an online readable format. The collection includes great classical literature and more recent works where the U.S. copyright has expired. These books are yours to read and use without restrictions.

Source Code - Want to change a program or know how it works? Open Source provides the source code for its programs so that anyone can use, modify or learn how to write those programs themselves. Visit the GNU source code repositories to download the source.


Education


Study at Harvard, Stanford or MIT - Open edX provides free online courses from Harvard, MIT, Columbia, UC Berkeley and other top Universities. Hundreds of courses for almost all major subjects and course levels. Open edx also offers some paid courses and selected certifications.

Linux Manual Pages - A man or manual page is a form of software documentation found on Linux/Unix operating systems. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts.