JsocWiki

SUM API
Storage Unit Management Subsystem (SUMS)
-------------------------------------------------------------

/* SUM.h */
#ifndef SUM_INCL
#define SUM_VERSION_NUM    (1.0)
#define DBCONNECT "DSOWNER/HMI4SDO@hmidb"
#include 
#include      /* need to repeat this for pro-c precompiler */

typedef uint64_t SUMID_t;

/* Bitmap of modes set in a SUM_t structure */
#define ARCH 1          /* archive the storage unit to tape */
#define TEMP 2          /* the storage unit is temporary */
#define PERM 4          /* the storage unit is permanent */
#define TOUCH 8         /* tdays gives the storage unit retention time */
#define RETRIEVE 16     /* retrieve from tape */
#define NORETRIEVE 32   /* don't retrieve from tape */
#define FULL 1024       /* also set this to get full info from DB query */

#define SUM_INCL
#endif

-------------------------------------------------------------------
This is found in sum_rpc.h:

typedef struct SUM_struct
{
  SUMID_t uid;
  CLIENT *cl;            /* client handle for calling sum_svc */
  SUM_info_t *sinfo;     /* info from sum_main for SUM_info() call */
  int debugflg;          /* verbose debug mode if set */
  int mode;              /* bit map of various modes */
  int tdays;             /* touch days for retention */
  int group;             /* group # for the given dataseries */
  int storeset;          /* assign storage from JSOC, DSDS, etc. Default JSOC*/
  int status;            /* return status on calls. 1 = error, 0 = success */
  double bytes;
  char *dsname;          /* dataseries name */
  char *username;        /* user's login name */
  char *history_comment; /* history comment string */
  int reqcnt;            /* # of entries in arrays below */
  uint64_t *dsix_ptr;    /* ptr to array of dsindex uint64_t */
  char **wd;             /* ptr to array of char * */
} SUM_t;

typedef struct SUMEXP_struct
{
  SUMID_t uid;
  int reqcnt;           /* # of entries in arrays below */
  char *host;           /* hostname target of scp call */
  char **src;           /* ptr to char * of source dirs */
  char **dest;          /* ptr to char * of destination dirs */
} SUMEXP_t;

-------------------------------------------------------------------
This is found in sum_info.h:

struct SUM_info_struct
{
  struct SUM_info_struct *next;
  uint64_t sunum;               //aka ds_index
  char online_loc[81];
  char online_status[5];
  char archive_status[5];
  char offsite_ack[5];
  char history_comment[81];
  char owning_series[81];
  int storage_group;
  double bytes;
  char creat_date[32];
  char username[11];
  char arch_tape[21];
  int arch_tape_fn;
  char arch_tape_date[32];
  char safe_tape[21];
  int safe_tape_fn;
  char safe_tape_date[32];
  int pa_status;
  int pa_substatus;
  char effective_date[20];
};
typedef struct SUM_info_struct SUM_info_t;

--------------------------------------------------------------------------

SUM_t *SUM_open(char *server, char *db, int (*history)(const char *fmt, ...))

        A DRMS instance opens a session with SUMS. It gives the  server
        name to connect to, defaults to SUMSERVER env else SUMSERVER define.
        The db name has been depricated and has no effect. The db will be
        the one that sum_svc was started with, e.g. sum_svc hmidb.
        The history is a printf type logging function.
        Returns a pointer to a SUM handle that is
        used to identify this user for this session. 
        Returns NULL on failure.
        Currently the dsix_ptr[] and wd[] arrays are malloc'd to size
        SUMARRAYSZ (512).

--------------------------------------------------------------------------

int SUM_close(SUM_t *sum, int (*history)(const char *fmt, ...))

        Closes the session. Returns 0 on success, else error code. 
        Will release all
        read-only storage and release all uncommitted allocated storage and 
        free any other resources for this SUM handle. 

--------------------------------------------------------------------------

int SUM_get(SUM_t *sum, int (*history)(const char *fmt, ...))

        Gets the location of the storage units given by the dsindexes.
        Marks the storage units as open for read.
        Return 0 on success with data available, 1 on error, or
        RESULT_PEND when the data will come from tape (call SUM_poll()
        or SUM_wait() to get completion msg. NOTE: Caller must check
        sum->status for any errors after SUM_poll() or final SUM_wait()).
        NOTE: You can call to get any number of storage unit (reqcnt).
        One completion message will be received when all units are online.
        If you get back an error status, you will not know if any particular
        storage unit failed. All the reqcnt storage units stand or fall
        as a team. If you want resolution at the individual storage unit
        level, you should make seperate SUM_get() calls.
        If you make another SUM_get() call before you do a SUM_wait()
        there will be two completion messages pending and SUM_wait() will
        return after the first one and you will not know which one did
        complete and there will still be another one pending. So keep the
        SUM_get()/SUM_wait() calls paired, unless you want to explicitly
        program for something more complex.

The caller sets:
SUMID   = the open id
mode    = RETRIEVE | NORETRIEVE to get any offline dataunits from tape 
          storage or not. Also TOUCH if want to change online retention time.
tdays   = touch days for online retention. Always used regardless of TOUCH mode
          if the SU was read from tape.
reqcnt  = Number of dsindex values given below to get
dsix_ptr= Pointer to array of reqcnt uint64_t to indicate DB index of 
          the dataunits

The function returns:
0 on success w/ data available,
1 on error,
4 on connection reset by peer (sum_svc probably gone),
32 RESULT_PEND. Reading from tape, answer will be sent later. The user should
   call SUM_wait() or SUM_poll() to get the answer.

If success then:
  wd    = Array of char * pointing to the wd of each dsindex given. Value
          is empty string for any non-existing storage unit, or an offline
          storage unit when mode = NORETRIEVE.

--------------------------------------------------------------------------

int SUM_alloc(SUM_t *sum, int (*history)(const char *fmt, ...))

        Assigns storage from /SUM and does mkdir and reports wd. The dir
        is owned by the calling user. This is used when an application wants 
        to make datarecords and put them in the managed /SUM storage. 
        The application makes a SUM_alloc() call for each storage unit that
        it wants to output datarecords to.
        Also used internally to allocate storage for dataunits being retrieved 
        from tape.
        (An application can make multiple SUM_alloc() calls, while previously
        there was only one alloc for any pe map file. Note that there is no
        longer any subdir naming template as prog:, level:, and series: 
        no longer exits. Also the dsindex in now assinged at the start
        rather then at the end of storage unit (dataset) creation. )
        NOTE: Currently you are restricted to make only one alloc at a time,
        i.e. reqcnt must be 1.

The caller sets:
SUMID   = the open id
bytes   = number of bytes to allocate

The function returns:
Error code, else 0 on success with:
dsix_ptr= Pointer to dsindex assigned to this storage unit. The application
          associates this dsindex with every datarecord that it creates in
          this storage unit.
wd      = Pointer to string giving the allocated wd. It is of the form of
          /SUM2/D123456/ where D123456 is a unique number supplied by the DB
          for each SUM_alloc() call (acutally can be the dsindex). 
          The datasegment records are created under this wd by the application
          with file names of the form record_666.segment_001.fits. 
          Where 666 represents the unique record number assigned by the 
          JSOC Data Record Managment System and 001 represents the first of
          possible multiple datasegments written. (Check with Rasmus.)

--------------------------------------------------------------------------

int SUM_alloc2(SUM_t *sum, uint64_t sunum, int (*history)(const char *fmt, ...))

        Assigns storage from /SUM for the given sunum (i.e. ds_index)
        and does mkdir and reports wd. NOTE: This is designed to replicate
        locally, data from a remote SUMS. The sunum must not be from the
        range of assigned sunum's for the callers local SUMS. The sunum
        will first be validated as not belonging to this SUMS.
        The dir is owned by the calling user. 
        The application makes a SUM_alloc2() call for each storage unit that
        it wants to replicate data segments to.
        NOTE: Currently you are restricted to make only one alloc at a time,
        i.e. reqcnt must be 1.

The caller sets in sum:
SUMID   = the open id
bytes   = number of bytes to allocate

The function returns:
Error code, else 0 on success with:
dsix_ptr= Pointer to dsindex assigned to this storage unit. In this case, 
          it will be the given sunum.
wd      = Pointer to string giving the allocated wd. It is of the form of
          /SUM2/D123456/ where 123456 is the given sunum.

--------------------------------------------------------------------------

int SUM_put(SUM_t *sum, int (*history)(const char *fmt, ...))

        Puts storage units from allocated storage to the DB catalog.
        Upon success the wds are owned by production.
        NOTE: All the mode, tdays, group, DB index and wd values must be
        for the same dsname.

The caller sets:
SUMID   = the open id
mode    = [ARCH | TEMP | PERM] + TOUCH for a normal, temporary or permanent
          cataloging with touch option to give tdays below
tdays   = If TOUCH applies, number of days to retain the storage unit
dsname  = dataseries name
group   = the storage group # for this dataseries
reqcnt  = Number of dsindex values given below to put
dsix_ptr= Pointer to array of reqcnt uint64_t to indicate DB index of 
          the dataunits
wd      = Array of char * pointing to the wd of each dsindex given. Value
          is NULL for any missing dataset

The function returns non-0 on error. A 1 is a fatal error, see the sum_svc
log file. A 2 is a null wd that was given and skipped. Normally the caller 
would not send blank wds.

Sample:
uint64_t *dsixpt;
char **cptr;

  sum->reqcnt = 3;
  dsixpt = sum->dsix_ptr;
  *dsixpt++ = index0;        /* ds_index of alloced data segment */
  *dsixpt++ = index1;
  *dsixpt = index2;
  cptr = sum->wd;
  *cptr = (char *)malloc(64);
  strcpy(*cptr, alloc_wd0);
  *cptr++;
  *cptr = (char *)malloc(64);
  strcpy(*cptr, alloc_wd1);
  *cptr++;
  *cptr = (char *)malloc(64);
  strcpy(*cptr, alloc_wd2);

  if(SUM_put(sum, printf)) {    /* save the data segments for archiving */
    printf("Error: on SUM_put()\n");
  }
  else {
    cptr = sum->wd; 
    for(i=0; i < sum->reqcnt; i++) {
      printf("The put wd = %s\n", *cptr++); 
    }
  }
        
--------------------------------------------------------------------------

int SUM_poll(SUM_t *sum)

(Normally only used by DRMS)

   Check if a previous request is complete.
 * Return 0 = msg complete, the sum has been updated
 * TIMEOUTMSG = msg still pending, try again later
 * ERRMSG = fatal error

NOTE: Upon msg complete return, sum->status != 0 if error anywhere in the
 path of the request that initially returned the RESULT_PEND status.

--------------------------------------------------------------------------

int SUM_wait(SUM_t *sum)

(Normally only used by DRMS)

   Wait until previous request is complete
 * Return 0 = msg complete, the sum has been updated
 * ERRMSG = fatal error

NOTE: Upon msg complete return, sum->status != 0 if error anywhere in the
 path of the request that initially returned the RESULT_PEND status.

--------------------------------------------------------------------------

int SUM_info(SUM_t *sum, uint64_t sunum, int (*history)(const char *fmt, ...))

        Returns the sum_main table info for the given sunum (i.e. ds_index)

Sample use:
  SUM_info_t *sinfo;

  if(SUM_info(sum, 2650355, printf)) {
    printf("Fail on SUM_info() in main3\n");
  }
  else {
    sinfo = sum->sinfo;
    printf("sum_info online_loc = %s\n", sinfo->online_loc);
    printf("sum_info online_status = %s\n", sinfo->online_status);
    printf("sum_info archive_status = %s\n", sinfo->archive_status);
    printf("sum_info creat_date = %s\n", sinfo->creat_date);
    printf("sum_info arch_tape = %s\n", sinfo->arch_tape);
    printf("sum_info arch_tape_fn = %d\n", sinfo->arch_tape_fn);
    printf("sum_info arch_tape_date = %s\n", sinfo->arch_tape_date);

  }

The function returns:
Error code, else 0 on success with sum->sinfo pointing to:
struct SUM_info_struct
{
  struct SUM_info_struct *next;
  uint64_t sunum;               //aka ds_index
  char online_loc[80];
  char online_status[5];
  char archive_status[5];
  char offsite_ack[5];
  char history_comment[80];
  char owning_series[80];
  int storage_group;
  double bytes;
  char creat_date[32];
  char username[10];
  char arch_tape[20];
  int arch_tape_fn;
  char arch_tape_date[32];
  char safe_tape[20];
  int safe_tape_fn;
  char safe_tape_date[32];
  int pa_status;
  int pa_substatus;
  char effective_date[20];
} SUM_info_t;
typedef struct SUM_info_struct SUM_info_t;


--------------------------------------------------------------------------

int SUM_infoEx(SUM_t *sum, int (*history)(const char *fmt, ...))

        Returns the sum_main/sum_partn_alloc table info for the given 
        sunums (up to 512)
        NOTE: Advise max of 64 to prevent excessive keylist scanning.
        NOTE: If use this in conjuction with DRMS, there may be a problem
              with crashing sum_svc. See Art's or Phil's code for the way to 
              handle using this with DRMS.

Sample use:
  SUM_info_t *sinfo;
  uint64_t *dsixpt;

  sum->reqcnt = 4;
  sum->sinfo = NULL;            //allow auto malloc
  dsixpt = sum->dsix_ptr;
  *dsixpt++ = 6379855;          //fill in sunums 
  *dsixpt++ = 40954592;
  *dsixpt++ = 1433435;
  *dsixpt = 40350694;
  if(SUM_infoEx(sum, printf)) {
    printf("\nFail on SUM_infoEx()\n");
  }
  else {
    sinfo = sum->sinfo;
    while(sinfo) {
      printf("\nsum_info username = %s\n", sinfo->username);
      printf("sum_info online_loc = %s\n", sinfo->online_loc);
      printf("sum_info online_status = %s\n", sinfo->online_status);
      printf("sum_info archive_status = %s\n", sinfo->archive_status);
      printf("sum_info owning_series = %s\n", sinfo->owning_series);
      printf("sum_info creat_date = %s\n", sinfo->creat_date);
      printf("sum_info arch_tape = %s\n", sinfo->arch_tape);
      printf("sum_info arch_tape_fn = %d\n", sinfo->arch_tape_fn);
      printf("sum_info arch_tape_date = %s\n", sinfo->arch_tape_date);
      printf("sum_info pa_status = %d\n", sinfo->pa_status);
      printf("sum_info pa_substatus = %d\n", sinfo->pa_substatus);
      printf("sum_info effective_date = %s\n", sinfo->effective_date);
      sinfo = sinfo->next;
    }
    SUM_infoEx_free(sum);
  }

NOTES: Returns data in the order of the sunums given. Do not give duplicate
sunums or this order is violated. If you give a non-existing sunum, the 
returned online_loc is NULL.

--------------------------------------------------------------------------

int SUM_infoArray(SUM_t *sum, uint64_t *dxarray, int reqcnt, int (*history)(const char *fmt, ...))

        Returns the sum_main/sum_partn_alloc table info for the given 
        sunums up to MAXSUNUMARRAY (65536).
        NOTE: Always allocates the memory needed for the answers at sum->sinfo.
        NOTE: For reqcnt > 128, this is much faster than SUM_infoEx().
        NOTE: If use this in conjuction with DRMS, the same note may apply
              that is in SUM_infoEx(), i.e.:
              See Art's or Phil's code for the way to 
              handle using this with DRMS.

Sample use:
  SUM_info_t *sinfo;
  uint64_t dxarray[MAXSUNUMARRAY];

  sum->reqcnt = 1024;
  sunum = 187699530;
  for(i=0; i < sum->reqcnt; i++) {
    dxarray[i] = sunum++;
  }
  if(SUM_infoArray(sum, &dxarray, sum->reqcnt, printf)) {
    printf("\nFail on SUM_infoArray()\n");
  }
  else {
    sinfo = sum->sinfo;
    for(i=0; i < sum->reqcnt; i++) {
      printf("\nsum_info sunum = %u\n", sinfo->sunum);
      printf("sum_info username = %s\n", sinfo->username);
      printf("sum_info online_loc = %s\n", sinfo->online_loc);
      printf("sum_info online_status = %s\n", sinfo->online_status);
      printf("sum_info archive_status = %s\n", sinfo->archive_status);
      printf("sum_info owning_series = %s\n", sinfo->owning_series);
      printf("sum_info bytes = %g\n", sinfo->bytes);
      printf("sum_info creat_date = %s\n", sinfo->creat_date);
      printf("sum_info arch_tape = %s\n", sinfo->arch_tape);
      printf("sum_info arch_tape_fn = %d\n", sinfo->arch_tape_fn);
      printf("sum_info arch_tape_date = %s\n", sinfo->arch_tape_date);
      printf("sum_info pa_status = %d\n", sinfo->pa_status);
      printf("sum_info pa_substatus = %d\n", sinfo->pa_substatus);
      printf("sum_info effective_date = %s\n", sinfo->effective_date);
      sinfo = sinfo->next;
    }
    SUM_infoArray_free(sum); //must free when done, else double free in close
  }

NOTE: Returns non-0 on error. 
      Error 4 is Connection reset by peer, sum_svc probably gone.
NOTES: Always returns data in the order requested. Will handle dup sunum.
If you give a non-existing sunum, the returned online_loc is NULL.

--------------------------------------------------------------------------

int SUM_delete_series(char *filename, int (*history)(const char *fmt, ...))

/* Called by the delete_series program before it deletes the series table.
 * Called with a pointer to a filename that has the sunums 
 * that are associated with the series about to be deleted.
 * Returns 1 on error, else 0.
*/
This will mark all the given storage units as delete pending with a 
substatus of DADPDELSU to not do any Records.txt processing for the
storage unit when it is deleted, as the DRMS may have reused the 
record numbers in the Records.txt file.

--------------------------------------------------------------------------

int SUM_export(SUMEXP_t *sumexp, int (*history)(const char *fmt, ...))

/* Will take a request (typically from remotesums_ingest)
 * and do an scp for the given host, source and target dirs.
 * The ssh-agent must be set up properly for this scp to complete.
 * Returns 0 on success, else 1.

Example of use is in:
/home/production/cvs/JSOC/base/sums/apps/main2.c

--------------------------------------------------------------------------

int SUM_nop(SUM_t *sum, int (*history)(const char *fmt, ...))

/* See if sum_svc is still alive. Return 0 if ok, 1 on timeout,
 * 4 on error (like unable to connect, i.e. the sum_svc is gone),
 * 5 tape_svc is gone (new 03Mar2011)

--------------------------------------------------------------------------

EXAMPLE OF USE:

See cvsroot/PROTO/src/SUM/main.c

with corresponding make in Makelinuxia64.mk and Makelinux4.mk

The SUM API library is in:

cvsroot/PROTO/src/libSUMAPI.d (OLD)

and

cvs/jsoc/src/base/sumsapi

--------------------------------------------------------------------------


DISCUSSION:

The SUMS runs as a server sum_svc, which the SUM_open() connects with via
a socket. It can decide how to serialize calls to the DB.



--------------------------------------------------------------------------
20Jan2005

Here's how the SUMS might be used.

When the DRMS first starts it calls SUM_open().
When the DRMS gets a call to write a record it needs a wd to write
the record to. If none is assigned, then it calls SUM_alloc() to get a 
storage unit and it also gets back a dsindex to associate with this data record.

Subsequent records are written to this wd until the number of records are
in the storage unit, which the DRMS knows from the series definition. So when
the next record is to be written another SUM_alloc() must be done.

When the application finally returns to pe, it indicates all the storage
units that were allocated and that need a SUM_put() done on them.
This happens on the return to pe so that an abort and release of everything
can be an option that the module selects in the end.

All the storage units are put one by one with a SUM_put() call with the 
archive mode and retention time and other ancillary info.
This would allow a module to produce seperate archivable,
temporary and permanenent datasets, compared to mdi which requires that all
output ds have the same archive properties.

JsocWiki: SumsApi (last edited 2013-05-01 04:35:24 by localhost)