- Tags plugin has been removed, its functionality has been moved into background
- The classad plugin has been added
-lglobus_common_${nothrflavour} \
-lglobus_gssapi_gsi_${nothrflavour}
+ifneq (${classads_prefix},/usr)
+ classadslib := -L${classads_prefix}/lib -lclassad
+endif
+
+CLASSADPLUGIN_LIBS:= ${classadslib} -lstdc++
+
+CLASSADPLUGIN_LOBJS:= classad_plugin.lo
+
+
GLOBUS_CFLAGS:=-I${globus_prefix}/include/${nothrflavour}
DEBUG:=-g -O0 -DDEBUG
LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS}
INSTALL:=libtool --mode=install install
-ifneq (${classads_prefix},/usr)
- classadslib := -L${classads_prefix}/lib -lclassad
-endif
-
daemon:=glite-jp-primarystoraged
example:=jpps-test dag-deps
ps_prefix:=jpps_
is_prefix:=jpis_
sample_jobs:=sample_job_aborted sample_job_cleared sample_job_tagged_done sample_job_waiting
-plugins:=glite-jp-tags.la glite-jp-ftpdauth.la glite-jp-sandbox.la
+plugins:=glite-jp-tags.la glite-jp-ftpdauth.la glite-jp-classad.la glite-jp-sandbox.la
HDRS_I=file_plugin.h
HDRS_S=builtin_plugins.h backend.h feed.h
dag-deps: ${DAG_OBJS}
${LINKXX} -o $@ ${DAG_OBJS} ${classadslib} ${GSOAPLIB}
-
JobProvenancePS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat
cp ${stagedir}/interface/JobProvenanceTypes.wsdl .
${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $<
${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $<
rm -f JobProvenanceTypes.wsdl
+glite-jp-classad.la: ${CLASSADPLUGIN_LOBJS}
+ ${SOLINK} -o $@ ${CLASSADPLUGIN_LOBJS} ${CLASSADPLUGIN_LIBS}
${ps_prefix}Client.c ${ps_prefix}ClientLib.c \
${ps_prefix}Server.c ${ps_prefix}ServerLib.c \
glite-jp-sandbox.la: sandbox_plugin.lo
${SOLINK} -o $@ sandbox_plugin.lo ${LIBTARLIB}
-glite-jp-tags.la: tags_plugin.lo
- ${SOLINK} -o $@ tags_plugin.lo
-
glite-jp-ftpdauth.la: ftpd_auth.lo mysql.lo
${SOLINK} -o $@ ftpd_auth.lo mysql.lo ${COMMONLIB} ${TRIOLIB} ${MYSQLIB}
+#glite-jp-classad.lo: classad_plugin.c
+# ${LTCOMPILE} -DPLUGIN_DEBUG -o $@ -c $<
+
%.lo: %.c
${LTCOMPILE} -o $@ -c $<
/** Retrieve value(s) of an attribute.
\param[in] fpctx Plugin context.
\param[in] handle Handle of the opened file.
+\param[in] ns Namespace of queried attribute.
\param[in] attr Queried attribute.
\param[out] attrval GLITE_JP_ATTR_UNDEF-terminated list of value(s) of the attribute.
If there are more and there is an interpretation of their order
\retval ENOSYS this attribute is not defined by this type of file
\retval ENOENT no value is present
*/
- int (*attr)(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval);
+ int (*attr)(void *fpctx,void *handle,const char *ns, const char *attr,glite_jp_attrval_t **attrval);
/** File type specific operation.
\param[in] fpctx Plugin context.
#include "builtin_plugins.h"
static struct {
- char *class,*uri;
- glite_jpps_fplug_data_t **plugins;
- int nplugins;
-} *known_classes;
-
-static int tags_index;
-
+ char *namespace;
+ glite_jpps_fplug_data_t **plugins;
+ int nplugins;
+
+} *known_namespaces;
+
+static char* get_namespace(const char* attr){
+ char* namespace = strdup(attr);
+ char* colon = strrchr(namespace, ':');
+ if (colon)
+ namespace[strrchr(namespace, ':') - namespace] = 0;
+ else
+ namespace[0] = 0;
+ return namespace;
+}
-static void scan_classes(glite_jp_context_t ctx)
+static void scan_namespaces(glite_jp_context_t ctx)
{
- int i,j,k;
- glite_jpps_fplug_data_t *pd;
+ int i,j,k;
+ glite_jpps_fplug_data_t *pd;
if (!ctx->plugins) return;
+
for (i=0; ctx->plugins[i]; i++) {
- pd = ctx->plugins[i];
-
- for (j=0; pd->classes[j]; j++) {
- for (k=0; known_classes && known_classes[k].class
- && strcmp(pd->classes[j],known_classes[k].class);
- k++);
- if (known_classes && known_classes[k].class) {
- known_classes[k].plugins = realloc(known_classes[k].plugins,
- (known_classes[k].nplugins + 2) * sizeof(glite_jpps_fplug_data_t *));
- known_classes[k].plugins[known_classes[k].nplugins++] = pd;
- known_classes[k].plugins[known_classes[k].nplugins] = NULL;
- }
- else {
- known_classes = realloc(known_classes,(k+2) * sizeof *known_classes);
- known_classes[k].class = pd->classes[j];
- known_classes[k].uri = pd->uris[j];
- known_classes[k].plugins = malloc(2 * sizeof(glite_jpps_fplug_data_t *));
- known_classes[k].plugins[0] = pd;
- known_classes[k].plugins[1] = NULL;
- known_classes[k].nplugins = 1;
- memset(known_classes+k+1,0,sizeof *known_classes);
- if (!strcmp(known_classes[k].uri,GLITE_JP_FILETYPE_TAGS)) tags_index = k;
- }
+ pd = ctx->plugins[i];
+
+ if (pd->namespaces){
+ for (j=0; pd->namespaces[j]; j++) {
+ for (k=0; known_namespaces && known_namespaces[k].namespace
+ && strcmp(pd->namespaces[j],known_namespaces[k].namespace); k++) {};
+
+ if (known_namespaces && known_namespaces[k].namespace) {
+ printf("Adding new plugin into namespace %s\n", known_namespaces[k].namespace);
+ known_namespaces[k].plugins = realloc(known_namespaces[k].plugins,
+ (known_namespaces[k].nplugins + 2) * sizeof(glite_jpps_fplug_data_t *));
+ known_namespaces[k].plugins[known_namespaces[k].nplugins++] = pd;
+ known_namespaces[k].plugins[known_namespaces[k].nplugins] = NULL;
+ known_namespaces[k].namespace = pd->namespaces[j];
+ }
+ else {
+ printf("Adding new namespace %s\n", pd->namespaces[j]);
+ known_namespaces = realloc(known_namespaces,(k+2) * sizeof *known_namespaces);
+ known_namespaces[k].plugins = malloc(2 * sizeof(glite_jpps_fplug_data_t *));
+ known_namespaces[k].plugins[0] = pd;
+ known_namespaces[k].plugins[1] = NULL;
+ known_namespaces[k].nplugins = 1;
+ known_namespaces[k].namespace = pd->namespaces[j];
+ memset(known_namespaces+k+1,0,sizeof *known_namespaces);
+ }
+ }
}
- }
+ }
}
static int merge_attrvals(glite_jp_attrval_t **out,int nout,const glite_jp_attrval_t *in)
return nout+nin;
}
+void process_files(glite_jp_context_t ctx, const char *job, glite_jp_attrval_t** out, int* nout, const char* attr, const glite_jpps_fplug_data_t* plugin, const char* class, const char* uri, const char *ns){
+ void *ph, *beh;
+ char** names = NULL;
+ int nnames = glite_jppsbe_get_names(ctx, job, class, &names);
+ int n;
+ for (n = 0; n < nnames; n++)
+ if (! glite_jppsbe_open_file(ctx,job,class, names[n], O_RDONLY, &beh)) {
+ if (!plugin->ops.open(plugin->fpctx,beh,uri,&ph)) {
+ glite_jp_attrval_t* myattr;
+ // XXX: ignore errors
+ if (!plugin->ops.attr(plugin->fpctx,ph,ns,attr,&myattr)) {
+ int k;
+ for (k=0; myattr[k].name; k++) {
+ myattr[k].origin = GLITE_JP_ATTR_ORIG_FILE;
+ trio_asprintf(&myattr[k].origin_detail,"%s %s", uri, names[n] ? names[n] : "");
+ }
+ *nout = merge_attrvals(out,*nout,myattr);
+ free(myattr);
+ }
+ plugin->ops.close(plugin->fpctx, ph);
+ }
+ glite_jppsbe_close_file(ctx,beh);
+ }
+}
+
glite_jpps_get_attrs(glite_jp_context_t ctx,const char *job,char **attr,int nattr,glite_jp_attrval_t **attrs_out)
{
glite_jp_attrval_t *meta = NULL,*out = NULL;
char const **other = NULL;
int i,j,nmeta,nother,err = 0,nout = 0;
- struct { int class_idx;
- char *name;
- } *files = NULL;
- int nfiles = 0;
-
nmeta = nother = 0;
glite_jp_clear_error(ctx);
/* retrieve the metadata */
if (meta && (err = glite_jppsbe_get_job_metadata(ctx,job,meta))) goto cleanup;
- if (!known_classes) scan_classes(ctx);
-
-/* build a list of available files for this job */
- files = malloc(sizeof *files);
- files->class_idx = tags_index;
- files->name = NULL;
- nfiles = 1;
-
- for (i=0; known_classes[i].class; i++) {
- char **names = NULL;
- int nnames =
- glite_jppsbe_get_names(ctx,job,known_classes[i].class,&names);
- if (nnames < 0) continue; /* XXX: error ignored */
-
- if (nnames > 0) {
- files = realloc(files,(nfiles+nnames+1) * sizeof *files);
- for (j=0; j<nnames; j++) {
- files[nfiles].class_idx = i;
- files[nfiles++].name = names[j];
+ if (!known_namespaces) scan_namespaces(ctx);
+
+/* loop over the attributes */
+ int k, l, m;
+ void* beh;
+ for (i = 0; i < nother; i++){
+ if (! glite_jppsbe_read_tag(ctx, job, other[i], &out))
+ nout++;
+ for (j = 0; known_namespaces[j].namespace; j++) {
+ void* ph;
+ char* attr_namespace = get_namespace(other[i]);
+ if (strcmp(attr_namespace, known_namespaces[j].namespace) == 0){
+ for (k = 0; known_namespaces[j].plugins[k]; k++)
+ for (l = 0; known_namespaces[j].plugins[k]->classes[l]; l++)
+ process_files(ctx, job, &out, &nout, other[i], known_namespaces[j].plugins[k]
+ , known_namespaces[j].plugins[k]->classes[l]
+ , known_namespaces[j].plugins[k]->uris[l]
+ , known_namespaces[j].namespace);
+ break;
}
- }
- free(names);
- }
-
-/* loop over the files */
- for (i=0; i<nfiles; i++) {
- void *beh;
- int ci;
-
- /* XXX: ignore error */
- if (!glite_jppsbe_open_file(ctx,job,
- known_classes[ci = files[i].class_idx].class,
- files[i].name,O_RDONLY,&beh))
- {
- for (j=0; j<known_classes[ci].nplugins; j++) {
- void *ph;
-
- glite_jpps_fplug_data_t *p =
- known_classes[ci].plugins[j];
- /* XXX: ignore error */
- if (!p->ops.open(p->fpctx,beh,known_classes[ci].uri,&ph)) {
-
- for (j=0; j<nother; j++) {
- glite_jp_attrval_t *myattr;
- /* XXX: ignore errors */
- if (!p->ops.attr(p->fpctx,ph,other[j],&myattr)) {
- int k;
- for (k=0; myattr[k].name; k++) {
- myattr[k].origin = GLITE_JP_ATTR_ORIG_FILE;
- trio_asprintf(&myattr[k].origin_detail,"%s %s",
- known_classes[ci].uri,
- files[i].name ? files[i].name : "");
- }
- nout = merge_attrvals(&out,nout,myattr);
- free(myattr);
- }
-
- }
- p->ops.close(p->fpctx,ph);
- }
- else {
- char *e;
- fprintf(stderr,"[%d] %s: %s\n",getpid(),known_classes[ci].class,
- e = glite_jp_error_chain(ctx));
- free(e);
- }
- }
-
- glite_jppsbe_close_file(ctx,beh);
- }
- else {
- char *e;
- fprintf(stderr,"[%d] %s: %s\n",getpid(),known_classes[ci].class,
- e = glite_jp_error_chain(ctx));
- free(e);
+ free(attr_namespace);
}
}
nout = merge_attrvals(&out,nout,meta);
+
free(meta); meta = NULL;
if (nout) {
free(other);
- if (files) for (i=0; i<nfiles; i++) free(files[i].name);
- free(files);
-
return err;
}
+
#define __GLITE_JP_BACKEND
#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include "feed.h"
void *handle
);
+int glite_jppsbe_file_attrs(
+ glite_jp_context_t ctx,
+ void *handle,
+ struct stat *buf
+);
+
int glite_jppsbe_pread(
glite_jp_context_t ctx,
void *handle,
-#define GLITE_JP_FILETYPE_TAGS "urn:org.glite.jp.primary:tags"
-#define GLITE_JP_FILETYPE_LB "urn:org.glite.jp.primary:lb"
-#define GLITE_JP_FILETYPE_ISB "urn:org.glite.jp.primary:isb"
-#define GLITE_JP_FILETYPE_OSB "urn:org.glite.jp.primary:osb"
+#define GLITE_JP_FILETYPE_TAGS "urn:org.glite.jp.primary:tags"
+#define GLITE_JP_FILETYPE_LB "urn:org.glite.jp.primary:lb"
+#define GLITE_JP_FILETYPE_CLASSAD "urn:org.glite.jp.primary:classad"
+#define GLITE_JP_FILETYPE_ISB "urn:org.glite.jp.primary:isb"
+#define GLITE_JP_FILETYPE_OSB "urn:org.glite.jp.primary:osb"
#define GLITE_JP_FPLUG_TAGS_APPEND 0
--- /dev/null
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <cclassad.h>
+#include <errno.h>
+
+#include "glite/lb/context.h"
+#include "glite/lb/jobstat.h"
+#include "glite/lb/events.h"
+#include "glite/lb/events_parse.h"
+#include "glite/lb/trio.h"
+#include "glite/jp/types.h"
+#include "glite/jp/context.h"
+#include "glite/jp/file_plugin.h"
+#include "glite/jp/builtin_plugins.h"
+#include "glite/jp/backend.h"
+#include "glite/jp/attr.h"
+#include "glite/jp/known_attr.h"
+
+//#define INITIAL_NUMBER_EVENTS 100
+//#define INITIAL_NUMBER_STATES EDG_WLL_NUMBER_OF_STATCODES
+//#define LB_PLUGIN_NAMESPACE "urn:org.glite.lb"
+
+//extern int processEvent(intJobStat *, edg_wll_Event *, int, int, char **);
+
+#include "glite/jp/builtin_plugins.h"
+
+typedef struct _classad_handle{
+ char* data;
+ struct cclassad* ad;
+ time_t timestamp;
+} classad_handle;
+
+static int classad_query(void *fpctx, void *handle, const char *ns, const char *attr, glite_jp_attrval_t **attrval);
+static int classad_open(void *fpctx, void *bhandle, const char *uri, void **handle);
+static int classad_open_str(void *fpctx, const char *str, const char *uri, const char *ns, void **handle);
+static int classad_close(void *fpctx, void *handle);
+
+int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) {
+ data->fpctx = ctx;
+
+ data->uris = calloc(2,sizeof *data->uris);
+ data->uris[0] = strdup(GLITE_JP_FILETYPE_CLASSAD);
+
+ data->classes = calloc(2,sizeof *data->classes);
+ data->classes[0] = strdup("classad");
+
+ data->namespaces = calloc(2, sizeof *data->namespaces);
+ data->namespaces[0] = strdup(GLITE_JP_JDL_NS);
+
+ data->ops.open = classad_open;
+ data->ops.close = classad_close;
+ data->ops.attr = classad_query;
+ data->ops.open_str = classad_open_str;
+
+#ifdef PLUGIN_DEBUG
+ fprintf(stderr,"classad_plugin: init OK\n");
+#endif
+
+ return 0;
+}
+
+
+void done(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) {
+ free(data->uris[0]);
+ free(data->classes[0]);
+ free(data->uris);
+ free(data->classes);
+ memset(data, 0, sizeof(*data));
+}
+
+
+static int classad_open(void *fpctx, void *bhandle, const char *uri, void **handle) {
+ glite_jp_context_t ctx = (glite_jp_context_t) fpctx;
+ glite_jp_error_t err;
+ classad_handle* h;
+ void* fh;
+ int retval = 0;
+
+ glite_jp_clear_error(ctx);
+ h = calloc(1, sizeof(classad_handle));
+ h->data = NULL;
+ struct stat fattr;
+ glite_jppsbe_file_attrs(ctx, bhandle, &fattr);
+ h->timestamp = fattr.st_mtime;
+
+ // read the classad file
+ char buf[1024];
+ size_t nbytes;
+ off_t offset = 0;
+
+ do{
+ if (! (retval = glite_jppsbe_pread(ctx, bhandle, buf, sizeof buf, offset, &nbytes))){
+ h->data = realloc(h->data, offset + nbytes);
+ memcpy(h->data + offset, buf, nbytes);
+ offset += nbytes;
+ }
+ else
+ goto fail;
+ }while(nbytes);
+
+ h->ad = cclassad_create(h->data);
+
+#ifdef PLUGIN_DEBUG
+ fprintf(stderr,"classad_plugin: opened\n");
+#endif
+
+ *handle = h;
+
+ return 0;
+
+fail:
+ err.code = EIO;
+ err.desc = NULL;
+ err.source = __FUNCTION__;
+ glite_jp_stack_error(ctx,&err);
+
+ return retval;
+}
+
+static int classad_open_str(void *fpctx,const char *str,const char *uri,const char *ns,void **handle){
+ classad_handle* h;
+
+ h = calloc(1, sizeof(classad_handle));
+ h->data = strdup(str);
+ h->ad = cclassad_create(h->data);
+ h->timestamp = 0;
+
+#ifdef PLUGIN_DEBUG
+ fprintf(stderr,"classad_plugin: opened\n");
+#endif
+
+ *handle = h;
+
+ return 0;
+
+}
+
+static int classad_close(void *fpctx,void *handle) {
+ classad_handle *h = (classad_handle *) handle;
+
+ cclassad_delete(h->ad);
+ free(h->data);
+ free(h);
+
+#ifdef PLUGIN_DEBUG
+ fprintf(stderr,"classad plugin: close OK\n");
+#endif
+ return 0;
+}
+
+
+static int classad_query(void *fpctx,void *handle, const char* ns, const char *attr,glite_jp_attrval_t **attrval) {
+ glite_jp_context_t ctx = (glite_jp_context_t) fpctx;
+ glite_jp_error_t err;
+ glite_jp_attrval_t *av = NULL;
+ classad_handle* h = (classad_handle*)handle;
+
+ glite_jp_clear_error(ctx);
+ memset(&err,0,sizeof err);
+ err.source = __FUNCTION__;
+
+ char *str = NULL;
+
+ if (! h->ad){
+ err.code = ENOENT;
+ err.desc = strdup("Classad plugin: No classad string, cannot get attr!");
+ *attrval = NULL;
+ printf("Exiting classat_query...\n");
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ if (cclassad_evaluate_to_string(h->ad, strrchr(attr, ':')+1, &str)) {
+ //struct stat fattr;
+ /*XXX ignore error */
+ //glite_jppsbe_file_attrs(ctx, h->bhandle, &fattr);
+ av = calloc(2, sizeof(glite_jp_attrval_t));
+ av[0].name = strdup(attr);
+ av[0].value = strdup(str);
+ av[0].size = -1;
+ av[0].timestamp = h->timestamp;
+ av[0].origin = GLITE_JP_ATTR_ORIG_FILE;
+ }
+ else{
+ printf("Classad plugin: bad attr!\n");
+ }
+
+ if (str) free(str);
+
+ *attrval = av;
+
+ if (av)
+ return 0;
+ else{
+ err.code = ENOENT;
+ err.desc = attr;
+ return glite_jp_stack_error(ctx,&err);
+ }
+}
+
#include "feed.h"
#include "tags.h"
+#include "tags2.h"
#include "backend.h"
#include "db.h"
}
}
+int glite_jppsbe_file_attrs(glite_jp_context_t ctx, void *handle, struct stat *buf){
+ glite_jp_error_t err;
+
+ assert(handle != NULL);
+
+ glite_jp_clear_error(ctx);
+ memset(&err,0,sizeof err);
+ err.source = __FUNCTION__;
+
+ if (! fstat(((fhandle)handle)->fd, buf)) {
+ err.code = errno;
+ err.desc = "Error calling fstat";
+ return -1;
+ }
+
+ return 0;
+}
+
int glite_jppsbe_pread(
glite_jp_context_t ctx,
void *handle,
return err.code;
}
+int glite_jppsbe_append_tag(
+ void *fpctx,
+ char *jobid,
+ glite_jp_attrval_t *attr
+)
+{
+ void *file_be;
+ glite_jp_error_t err;
+ glite_jp_context_t ctx = fpctx;
+ memset(&err,0,sizeof err);
+ err.source = __FUNCTION__;
+
+ if (glite_jppsbe_open_file(ctx,jobid,"tags",NULL,
+ O_RDWR|O_CREAT,&file_be)
+ // XXX: tags need reading to check magic number
+ ) {
+ err.code = EIO;
+ err.desc = "cannot open tags file";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ if (tag_append(ctx,file_be,attr))
+ {
+ err.code = EIO;
+ err.desc = "cannot append tag";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ if (glite_jppsbe_close_file(ctx,file_be))
+ {
+ err.code = EIO;
+ err.desc = "cannot close tags file";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ return 0;
+}
+
+
+int glite_jppsbe_read_tag(
+ void *fpctx,
+ const char *jobid,
+ const char *attr,
+ glite_jp_attrval_t **attrval
+)
+{
+ glite_jp_error_t err;
+ glite_jp_context_t ctx = fpctx;
+ struct tags_handle *h;
+
+ memset(&err,0,sizeof err);
+ err.source = __FUNCTION__;
+ h = malloc(sizeof (*h));
+ h->tags = NULL;
+ h->n = 0;
+
+ if (glite_jppsbe_open_file(ctx,jobid,"tags",NULL,
+ O_RDONLY,&(h->bhandle))
+ // XXX: tags need reading to check magic number
+ ) {
+ err.code = EIO;
+ err.desc = "cannot open tags file";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ if (tag_attr(ctx,h,attr,attrval)){
+ err.code = EIO;
+ err.desc = "cannot read tag";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ if (glite_jppsbe_close_file(ctx,h->bhandle))
+ {
+ err.code = EIO;
+ err.desc = "cannot close tags file";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ return 0;
+}
//static int sandbox_append(void *,void *,int,...);
static int sandbox_open(void *,void *,const char *uri,void **);
static int sandbox_close(void *,void *);
-static int sandbox_attr(void *,void *,const char *,glite_jp_attrval_t **);
+static int sandbox_attr(void *,void *,const char*,const char *,glite_jp_attrval_t **);
int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data)
data->classes = calloc(2,sizeof *data->classes);
data->classes[0] = strdup("sandbox");
+ data->namespaces = calloc(3, sizeof *data->namespaces);
+ data->namespaces[0] = strdup(GLITE_JP_ISB_NS);
+ data->namespaces[1] = strdup(GLITE_JP_OSB_NS);
+
data->ops.open = sandbox_open;
data->ops.close = sandbox_close;
data->ops.attr = sandbox_attr;
}
-static int sandbox_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval)
+static int sandbox_attr(void *fpctx,void *handle,const char *ns,const char *attr,glite_jp_attrval_t **attrval)
{
glite_jp_error_t err;
glite_jp_context_t ctx = fpctx;
{
CONTEXT_FROM_SOAP(soap,ctx);
void *file_be,*file_p;
- glite_jpps_fplug_data_t **pd = NULL;
glite_jp_attrval_t attr[2], meta[2];
attr[0].origin_detail = NULL; /* XXX */
attr[1].name = NULL;
- /* XXX: we assume just one plugin and also that TAGS plugin handles
- * just one uri/class */
+ /*if (glite_jppsbe_open_file(ctx,in->jobid,"tags",NULL,
+ O_RDWR|O_CREAT,&file_be)
+ // XXX: tags need reading to check magic number
+ ) {
+ err2fault(ctx,soap);
+ return SOAP_FAULT;
+ }
- if (glite_jpps_fplug_lookup(ctx,GLITE_JP_FILETYPE_TAGS,&pd)
- || glite_jppsbe_open_file(ctx,in->jobid,pd[0]->classes[0],NULL,
- O_RDWR|O_CREAT,&file_be)
- /* XXX: tags need reading to check magic number */
- ) {
- free(pd);
- err2fault(ctx,soap);
- return SOAP_FAULT;
- }
-
- /* XXX: assuming tag plugin handles just one type */
- if (pd[0]->ops.open(pd[0]->fpctx,file_be,GLITE_JP_FILETYPE_TAGS,&file_p)
- || pd[0]->ops.generic(pd[0]->fpctx,file_p,GLITE_JP_FPLUG_TAGS_APPEND,attr))
+ if (glite_jppsbe_close_file(ctx,file_be))
{
err2fault(ctx,soap);
- if (file_p) pd[0]->ops.close(pd[0]->fpctx,file_p);
- glite_jppsbe_close_file(ctx,file_be);
- free(pd);
return SOAP_FAULT;
- }
+ }*/
+ glite_jppsbe_append_tag(ctx,in->jobid,attr);
- if (pd[0]->ops.close(pd[0]->fpctx,file_p)
- || glite_jppsbe_close_file(ctx,file_be))
+ /*if (tag_append(ctx,file_be,attr))
{
- err2fault(ctx,soap);
- free(pd);
- return SOAP_FAULT;
- }
+ err2fault(ctx,soap);
+ return SOAP_FAULT;
+ }*/
/* XXX: ignore errors but don't fail silenty */
glite_jpps_match_attr(ctx,in->jobid,attr);
- free(pd);
return SOAP_OK;
err:
glite_jp_attrval_free(meta,0);
free(tags);
return glite_jp_stack_error(ctx,&err);
}
+
+int tag_append(void *fpctx,void *bhandle,glite_jp_attrval_t * tag)
+{
+ va_list ap;
+ char *hdr,*rec;
+ glite_jp_context_t ctx = fpctx;
+ uint32_t magic,hlen,rlen,rlen_n;
+ size_t r;
+ glite_jp_error_t err;
+
+ memset(&err,0,sizeof err);
+ err.source = __FUNCTION__;
+ glite_jp_clear_error(ctx);
+
+ printf("tagappend: %s,%s\n",tag->name,tag->value);
+
+ //assert(oper == GLITE_JP_FPLUG_TAGS_APPEND);
+
+ if (glite_jppsbe_pread(ctx,bhandle,&magic,sizeof magic,0,&r)) {
+ err.code = EIO;
+ err.desc = "reading magic number";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ if (r == 0) {
+ magic = htonl(TAGS_MAGIC);
+ if (glite_jppsbe_pwrite(ctx,bhandle,&magic,sizeof magic,0)) {
+ err.code = EIO;
+ err.desc = "writing magic number";
+ return glite_jp_stack_error(ctx,&err);
+ }
+ }
+ else if (r != sizeof magic) {
+ err.code = EIO;
+ err.desc = "can't read magic number";
+ return glite_jp_stack_error(ctx,&err);
+ }
+ else if (magic != htonl(TAGS_MAGIC)) {
+ err.code = EINVAL;
+ err.desc = "invalid magic number";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+/* XXX: origin is always USER, not recorded */
+ trio_asprintf(&hdr,"%ld %c",
+ tag->timestamp,tag->binary ? 'B' : 'S');
+
+ rlen = strlen(tag->name) + strlen(hdr) + 2 /* \0 after name and after hdr */ +
+ (r = tag->binary ? tag->size : (tag->value ? strlen(tag->value) : 0));
+
+ rlen_n = htonl(rlen);
+
+ rec = malloc(rlen + sizeof rlen_n);
+ *((uint32_t *) rec) = rlen_n;
+ strcpy(rec + sizeof rlen_n,tag->name);
+ strcpy(rec + (hlen = sizeof rlen_n + strlen(tag->name) + 1),hdr);
+
+ if (r) memcpy(rec + hlen + strlen(hdr) + 1,tag->value,r);
+ free(hdr);
+
+/* record format:
+ * - 4B length, net byte order
+ * - attr name, \0
+ * - %ld %c \0 (timestamp, B/S)
+ * - value
+ */
+ if (glite_jppsbe_append(ctx,bhandle,rec,rlen + sizeof rlen_n)) {
+ err.code = EIO;
+ err.desc = "writing tag record";
+ free(rec);
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ /* XXX: should add tag also to handle->tags, but it is never used
+ * currently */
+
+ return 0;
+}
+
+int tag_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval)
+{
+ struct tags_handle *h = handle;
+ glite_jp_error_t err;
+ glite_jp_context_t ctx = fpctx;
+ glite_jp_attrval_t *out = NULL;
+ int i,nout = 0;
+
+ memset(&err,0,sizeof err);
+ err.source = __FUNCTION__;
+
+ if (!h->tags) tagsread(fpctx,handle);
+
+ if (!h->tags) {
+ err.code = ENOENT;
+ err.desc = "no tags for this job";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ for (i=0; i<h->n; i++) if (!strcmp(h->tags[i].name,attr)) {
+ out = realloc(out,(nout+2) * sizeof *out);
+ glite_jp_attrval_copy(out+nout,h->tags+i);
+ nout++;
+ memset(out+nout,0,sizeof *out);
+ }
+
+ if (nout) {
+ *attrval = out;
+ return 0;
+ }
+ else {
+ err.code = ENOENT;
+ err.desc = "no value for this tag";
+ return glite_jp_stack_error(ctx,&err);
+ }
+}
+
+static int tagsread(void *fpctx,struct tags_handle *h)
+{
+ glite_jp_context_t ctx = fpctx;
+ uint32_t magic,rlen;
+ glite_jp_error_t err;
+ int r;
+ size_t off = sizeof rlen;
+ glite_jp_attrval_t *tp;
+ char *rp;
+
+ memset(&err,0,sizeof err);
+ err.source = __FUNCTION__;
+
+ glite_jp_clear_error(ctx);
+
+// read magic number
+ if (glite_jppsbe_pread(ctx,h->bhandle,&magic,sizeof magic,0,&r)) {
+ err.code = EIO;
+ err.desc = "reading magic number";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ if (r != sizeof magic) {
+ err.code = EIO;
+ err.desc = "can't read magic number";
+ return glite_jp_stack_error(ctx,&err);
+ }
+ else if (magic != htonl(TAGS_MAGIC)) {
+ err.code = EINVAL;
+ err.desc = "invalid magic number";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+
+ while (1) {
+ char *rec,type;
+ int rd;
+
+ // read record header
+ if (glite_jppsbe_pread(ctx,h->bhandle,&rlen,sizeof rlen,off,&r)) {
+ err.code = EIO;
+ err.desc = "reading record header";
+ return glite_jp_stack_error(ctx,&err);
+ }
+ if (r == 0) break;
+
+ if (r != sizeof rlen) {
+ err.code = EIO;
+ err.desc = "can't read record header";
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ off += r;
+ rec = malloc(rlen = ntohl(rlen));
+
+ // read whole record body thoroughly
+ for (rd=0; rd<rlen; rd+=r) // XXX: will loop on 0 bytes read
+ if (glite_jppsbe_pread(ctx,h->bhandle,rec+rd,rlen-rd,off+rd,&r)) {
+ err.code = EIO;
+ err.desc = "reading record body";
+ free(rec);
+ return glite_jp_stack_error(ctx,&err);
+ }
+
+ off += rlen;
+
+ // parse the record
+ h->tags = realloc(h->tags,(h->n+2) * sizeof *h->tags);
+ tp = h->tags+h->n++;
+ memset(tp,0,sizeof *tp);
+
+ tp->name = strdup(rec);
+ rp = rec + strlen(rec) + 1;
+
+ sscanf(rp,"%ld %c",&tp->timestamp,&type);
+ rp += strlen(rp) + 1;
+ switch (type) {
+ int i;
+
+ case 'B': tp->binary = 1; break;
+ case 'S': tp->binary = 0; break;
+ default: free(rec);
+ for (i=0; i<h->n; i++)
+ glite_jp_attrval_free(h->tags+i,0);
+ free(h->tags);
+ h->tags = NULL;
+ h->n = 0;
+
+ err.code = EINVAL;
+ err.desc = "invalid attr type (B/S)";
+ return glite_jp_stack_error(ctx,&err);
+ }
+ tp->value = malloc((r=rlen - (rp - rec)) + 1);
+ memcpy(tp->value,rp,r);
+ if (!tp->binary) tp->value[r] = 0;
+ tp->origin = GLITE_JP_ATTR_ORIG_USER;
+
+ free(rec);
+ }
+ return 0;
+}
+
+struct tags_handle {
+ void *bhandle;
+ int n;
+ glite_jp_attrval_t *tags;
+};
+
+int tag_append(void *fpctx,void *bhandle,glite_jp_attrval_t * tag);
int glite_jpps_tag_append(glite_jp_context_t,void *,const char *, const char *);
+int tag_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval);
+++ /dev/null
-#include <stdlib.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <stdint.h>
-
-#include <glite/jp/types.h>
-
-#include "file_plugin.h"
-#include "builtin_plugins.h"
-#include "backend.h"
-
-static int tagappend(void *,void *,int,...);
-static int tagopen(void *,void *,const char *uri,void **);
-static int tagclose(void *,void *);
-static int tagattr(void *,void *,const char *,glite_jp_attrval_t **);
-
-struct tags_handle {
- void *bhandle;
- int n;
- glite_jp_attrval_t *tags;
-};
-
-static int tagsread(void *,struct tags_handle *);
-
-#define TAGS_MAGIC 0x74c016f2 /* two middle digits encode version, i.e. 01 */
-
-static int tagdummy()
-{
- puts("tagdummy()");
- return -1;
-}
-
-int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data)
-{
- data->fpctx = ctx;
-
- data->uris = calloc(2,sizeof *data->uris);
- data->uris[0] = strdup(GLITE_JP_FILETYPE_TAGS);
-
- data->classes = calloc(2,sizeof *data->classes);
- data->classes[0] = strdup("tags");
-
- data->ops.open = tagopen;
- data->ops.close = tagclose;
- data->ops.attr = tagattr;
- data->ops.generic = tagappend;
-
- printf("tags_plugin: URI: \"%s\"; magic number: 0x%08lx\n",GLITE_JP_FILETYPE_TAGS,TAGS_MAGIC);
- return 0;
-}
-
-static int tagopen(void *fpctx,void *bhandle,const char *uri,void **handle)
-{
- struct tags_handle *h = calloc(1,sizeof *h);
- h->n = 0;
- h->bhandle = bhandle;
-
- *handle = h;
-
- return 0;
-}
-
-static int tagclose(void *fpctx,void *handle)
-{
- int i;
- struct tags_handle *h = handle;
-
- for (i=0; i<h->n; i++) glite_jp_attrval_free(h->tags+i,0);
- free(h->tags);
- free(h);
-
- return 0;
-}
-
-static int tagappend(void *fpctx,void *handle,int oper,...)
-{
- glite_jp_attrval_t *tag;
- va_list ap;
- char *hdr,*rec;
- glite_jp_context_t ctx = fpctx;
- struct tags_handle *h = handle;
- uint32_t magic,hlen,rlen,rlen_n;
- size_t r;
- glite_jp_error_t err;
-
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
- glite_jp_clear_error(ctx);
-
- va_start(ap,oper);
- tag = va_arg(ap,glite_jp_attrval_t *);
- va_end(ap);
-
- printf("tagappend: %s,%s\n",tag->name,tag->value);
-
- assert(oper == GLITE_JP_FPLUG_TAGS_APPEND);
-
- if (glite_jppsbe_pread(ctx,h->bhandle,&magic,sizeof magic,0,&r)) {
- err.code = EIO;
- err.desc = "reading magic number";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (r == 0) {
- magic = htonl(TAGS_MAGIC);
- if (glite_jppsbe_pwrite(ctx,h->bhandle,&magic,sizeof magic,0)) {
- err.code = EIO;
- err.desc = "writing magic number";
- return glite_jp_stack_error(ctx,&err);
- }
- }
- else if (r != sizeof magic) {
- err.code = EIO;
- err.desc = "can't read magic number";
- return glite_jp_stack_error(ctx,&err);
- }
- else if (magic != htonl(TAGS_MAGIC)) {
- err.code = EINVAL;
- err.desc = "invalid magic number";
- return glite_jp_stack_error(ctx,&err);
- }
-
-/* XXX: origin is always USER, not recorded */
- trio_asprintf(&hdr,"%ld %c",
- tag->timestamp,tag->binary ? 'B' : 'S');
-
- rlen = strlen(tag->name) + strlen(hdr) + 2 /* \0 after name and after hdr */ +
- (r = tag->binary ? tag->size : (tag->value ? strlen(tag->value) : 0));
-
- rlen_n = htonl(rlen);
-
- rec = malloc(rlen + sizeof rlen_n);
- *((uint32_t *) rec) = rlen_n;
- strcpy(rec + sizeof rlen_n,tag->name);
- strcpy(rec + (hlen = sizeof rlen_n + strlen(tag->name) + 1),hdr);
-
- if (r) memcpy(rec + hlen + strlen(hdr) + 1,tag->value,r);
- free(hdr);
-
-/* record format:
- * - 4B length, net byte order
- * - attr name, \0
- * - %ld %c \0 (timestamp, B/S)
- * - value
- */
- if (glite_jppsbe_append(ctx,h->bhandle,rec,rlen + sizeof rlen_n)) {
- err.code = EIO;
- err.desc = "writing tag record";
- free(rec);
- return glite_jp_stack_error(ctx,&err);
- }
-
- /* XXX: should add tag also to handle->tags, but it is never used
- * currently */
-
- return 0;
-}
-
-static int tagattr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval)
-{
- struct tags_handle *h = handle;
- glite_jp_error_t err;
- glite_jp_context_t ctx = fpctx;
- glite_jp_attrval_t *out = NULL;
- int i,nout = 0;
-
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if (!h->tags) tagsread(fpctx,handle);
-
- if (!h->tags) {
- err.code = ENOENT;
- err.desc = "no tags for this job";
- return glite_jp_stack_error(ctx,&err);
- }
-
- for (i=0; i<h->n; i++) if (!strcmp(h->tags[i].name,attr)) {
- out = realloc(out,(nout+2) * sizeof *out);
- glite_jp_attrval_copy(out+nout,h->tags+i);
- nout++;
- memset(out+nout,0,sizeof *out);
- }
-
- if (nout) {
- *attrval = out;
- return 0;
- }
- else {
- err.code = ENOENT;
- err.desc = "no value for this tag";
- return glite_jp_stack_error(ctx,&err);
- }
-}
-
-static int tagsread(void *fpctx,struct tags_handle *h)
-{
- glite_jp_context_t ctx = fpctx;
- uint32_t magic,rlen;
- glite_jp_error_t err;
- int r;
- size_t off = sizeof rlen;
- glite_jp_attrval_t *tp;
- char *rp;
-
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- glite_jp_clear_error(ctx);
-
-/* read magic number */
- if (glite_jppsbe_pread(ctx,h->bhandle,&magic,sizeof magic,0,&r)) {
- err.code = EIO;
- err.desc = "reading magic number";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (r != sizeof magic) {
- err.code = EIO;
- err.desc = "can't read magic number";
- return glite_jp_stack_error(ctx,&err);
- }
- else if (magic != htonl(TAGS_MAGIC)) {
- err.code = EINVAL;
- err.desc = "invalid magic number";
- return glite_jp_stack_error(ctx,&err);
- }
-
-
- while (1) {
- char *rec,type;
- int rd;
-
- /* read record header */
- if (glite_jppsbe_pread(ctx,h->bhandle,&rlen,sizeof rlen,off,&r)) {
- err.code = EIO;
- err.desc = "reading record header";
- return glite_jp_stack_error(ctx,&err);
- }
- if (r == 0) break;
-
- if (r != sizeof rlen) {
- err.code = EIO;
- err.desc = "can't read record header";
- return glite_jp_stack_error(ctx,&err);
- }
-
- off += r;
- rec = malloc(rlen = ntohl(rlen));
-
- /* read whole record body thoroughly */
- for (rd=0; rd<rlen; rd+=r) /* XXX: will loop on 0 bytes read */
- if (glite_jppsbe_pread(ctx,h->bhandle,rec+rd,rlen-rd,off+rd,&r)) {
- err.code = EIO;
- err.desc = "reading record body";
- free(rec);
- return glite_jp_stack_error(ctx,&err);
- }
-
- off += rlen;
-
- /* parse the record */
- h->tags = realloc(h->tags,(h->n+2) * sizeof *h->tags);
- tp = h->tags+h->n++;
- memset(tp,0,sizeof *tp);
-
- tp->name = strdup(rec);
- rp = rec + strlen(rec) + 1;
-
- sscanf(rp,"%ld %c",&tp->timestamp,&type);
- rp += strlen(rp) + 1;
- switch (type) {
- int i;
-
- case 'B': tp->binary = 1; break;
- case 'S': tp->binary = 0; break;
- default: free(rec);
- for (i=0; i<h->n; i++)
- glite_jp_attrval_free(h->tags+i,0);
- free(h->tags);
- h->tags = NULL;
- h->n = 0;
-
- err.code = EINVAL;
- err.desc = "invalid attr type (B/S)";
- return glite_jp_stack_error(ctx,&err);
- }
- tp->value = malloc((r=rlen - (rp - rec)) + 1);
- memcpy(tp->value,rp,r);
- if (!tp->binary) tp->value[r] = 0;
- tp->origin = GLITE_JP_ATTR_ORIG_USER;
-
- free(rec);
- }
- return 0;
-}