void oval_probe_session_destroy(oval_probe_session_t *sess)
{
	if (sess == NULL) {
		dE("Invalid session (NULL)");
		return;
	}

        oval_phtbl_free(sess->ph);
        oval_pext_free(sess->pext);
        oscap_free(sess);
}
int oval_probe_session_abort(oval_probe_session_t *sess)
{
	oval_ph_t *ph;

	if ((ph = oval_probe_handler_get(sess->ph, OVAL_SUBTYPE_ALL) ) == NULL) {
		dE("No probe handler for OVAL_SUBTYPE_ALL");
		return (-1);
	}

        return ph->func(OVAL_SUBTYPE_ALL, ph->uptr, PROBE_HANDLER_ACT_ABORT);
}
Exemple #3
0
/**
 * Collect an item
 * This function adds an item the collected object assosiated
 * with the given probe context.
 *
 * Returns:
 * 0 ... the item was succesfully added to the collected object
 * 1 ... the item was filtered out
 * 2 ... the item was not added because of memory constraints
 *       and the collected object was flagged as incomplete
 *-1 ... unexpected/internal error
 *
 * The caller must not free the item, it's freed automatically
 * by this function or by the icache worker thread.
 */
int probe_item_collect(struct probe_ctx *ctx, SEXP_t *item)
{
	SEXP_t *cobj_content;
	size_t  cobj_itemcnt;

	assume_d(ctx != NULL, -1);
	assume_d(ctx->probe_out != NULL, -1);
	assume_d(item != NULL, -1);

	cobj_content = SEXP_listref_nth(ctx->probe_out, 3);
	cobj_itemcnt = SEXP_list_length(cobj_content);
	SEXP_free(cobj_content);

	if (probe_cobj_memcheck(cobj_itemcnt) != 0) {

		/*
		 * Don't set the message again if the collected object is
		 * already flagged as incomplete.
		 */
		if (probe_cobj_get_flag(ctx->probe_out) != SYSCHAR_FLAG_INCOMPLETE) {
			SEXP_t *msg;
			/*
			 * Sync with the icache thread before modifying the
			 * collected object.
			 */
			if (probe_icache_nop(ctx->icache) != 0)
				return -1;

			msg = probe_msg_creat(OVAL_MESSAGE_LEVEL_WARNING,
			                      "Object is incomplete due to memory constraints.");

			probe_cobj_add_msg(ctx->probe_out, msg);
			probe_cobj_set_flag(ctx->probe_out, SYSCHAR_FLAG_INCOMPLETE);

			SEXP_free(msg);
		}

		return 2;
	}

        if (ctx->filters != NULL && probe_item_filtered(item, ctx->filters)) {
                SEXP_free(item);
		return (1);
        }

        if (probe_icache_add(ctx->icache, ctx->probe_out, item) != 0) {
                dE("Can't add item (%p) to the item cache (%p)", item, ctx->icache);
                SEXP_free(item);
                return (-1);
        }

        return (0);
}
Exemple #4
0
int probe_main (probe_ctx *ctx, void *arg)
{
        SEXP_t *probe_in, *name_ent, *file_ent, *bh_ent;
        char   file[PATH_MAX];
        size_t file_len = sizeof file;
        char   name[64];
        size_t name_len = sizeof name;
        oval_operation_t name_op, file_op;
        uint64_t collect_flags = 0;
        unsigned int i;

	// If probe_init() failed it's because there was no rpm config files
	if (arg == NULL) {
		probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_NOT_APPLICABLE);
		return 0;
	}

        /*
         * Get refs to object entities
         */
        probe_in = probe_ctx_getobject(ctx);
        name_ent = probe_obj_getent(probe_in, "name", 1);
        file_ent = probe_obj_getent(probe_in, "filepath", 1);

        if (name_ent == NULL || file_ent == NULL) {
                dE("Missing \"name\" (%p) or \"filepath\" (%p) entity", name_ent, file_ent);

                SEXP_free(name_ent);
                SEXP_free(file_ent);

                return (PROBE_ENOENT);
        }

        /*
         * Extract the requested operation for each entity
         */
        name_op = probe_ent_getoperation(name_ent, OVAL_OPERATION_EQUALS);
        file_op = probe_ent_getoperation(file_ent, OVAL_OPERATION_EQUALS);

        if (name_op == OVAL_OPERATION_UNKNOWN ||
            file_op == OVAL_OPERATION_UNKNOWN)
        {
                SEXP_free(name_ent);
                SEXP_free(file_ent);

                return (PROBE_EINVAL);
        }

        /*
         * Extract entity values
         */
        PROBE_ENT_STRVAL(name_ent, name, name_len, /* void */, strcpy(name, ""););
Exemple #5
0
int probe_icache_nop(probe_icache_t *cache)
{
        pthread_cond_t cond;

        dD("NOP");

        if (pthread_mutex_lock(&cache->queue_mutex) != 0) {
                dE("An error ocured while locking the queue mutex: %u, %s",
                   errno, strerror(errno));
                return (-1);
        }

        if (pthread_cond_init(&cond, NULL) != 0) {
                dE("Can't initialize icache queue condition variable (NOP): %u, %s",
                   errno, strerror(errno));
                return (-1);
        }

        if (__probe_icache_add_nolock(cache, NULL, NULL, &cond) != 0) {
                if (pthread_mutex_unlock(&cache->queue_mutex) != 0) {
                        dE("An error ocured while unlocking the queue mutex: %u, %s",
                           errno, strerror(errno));
                        abort();
                }

                pthread_cond_destroy(&cond);
                return (-1);
        }

        dD("Signaling `notempty'");

        if (pthread_cond_signal(&cache->queue_notempty) != 0) {
                dE("An error ocured while signaling the `notempty' condition: %u, %s",
                   errno, strerror(errno));

                pthread_cond_destroy(&cond);
                return (-1);
        }

        dD("Waiting for icache worker to handle the NOP");

        if (pthread_cond_wait(&cond, &cache->queue_mutex) != 0) {
                dE("An error ocured while waiting for the `NOP' queue condition: %u, %s",
                   errno, strerror(errno));
                return (-1);
        }

        dD("Sync");

        if (pthread_mutex_unlock(&cache->queue_mutex) != 0) {
                dE("An error ocured while unlocking the queue mutex: %u, %s",
                   errno, strerror(errno));
                abort();
        }

        pthread_cond_destroy(&cond);

        return (0);
}
static SEXP_t *create_item(const char *path, const char *filename, char *pattern,
			   int instance, char **substrs, int substr_cnt, oval_schema_version_t over)
{
	int i;
	SEXP_t *item;
        SEXP_t *r0;
	SEXP_t *se_instance, *se_filepath;
	char *text;

        if (strlen(path) + strlen(filename) + 1 > PATH_MAX) {
                dE("path+filename too long");
                return (NULL);
        }

	if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.4)) < 0) {
		pattern = text = NULL;
		se_instance = NULL;
	} else {
		text = substrs[0];
		se_instance = SEXP_number_newu_64((int64_t) instance);
	}
	if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.6)) < 0) {
		se_filepath = NULL;
	} else {
		const size_t path_len = strlen(path);
		/* Avoid 2 slashes */
		if (path_len >= 1 && path[path_len - 1] == FILE_SEPARATOR) {
			se_filepath = SEXP_string_newf("%s%s", path, filename);
		} else {
			se_filepath = SEXP_string_newf("%s%c%s", path, FILE_SEPARATOR, filename);
		}
	}

        item = probe_item_create(OVAL_INDEPENDENT_TEXT_FILE_CONTENT, NULL,
                                 "filepath", OVAL_DATATYPE_SEXP, se_filepath,
                                 "path",     OVAL_DATATYPE_STRING, path,
                                 "filename", OVAL_DATATYPE_STRING, filename,
                                 "pattern",  OVAL_DATATYPE_STRING, pattern,
                                 "instance", OVAL_DATATYPE_SEXP, se_instance,
                                 "line",     OVAL_DATATYPE_STRING, pattern,
                                 "text",     OVAL_DATATYPE_STRING, substrs[0],
                                 NULL);

	for (i = 1; i < substr_cnt; ++i) {
                probe_item_ent_add (item, "subexpression", NULL, r0 = SEXP_string_new (substrs[i], strlen (substrs[i])));
                SEXP_free (r0);
	}

	return item;
}
Exemple #7
0
static void probe_icache_item_setID(SEXP_t *item, SEXP_ID_t item_ID)
{
        SEXP_t  *name_ref, *prev_id;
        SEXP_t   uniq_id;
        uint32_t local_id;

        /* ((foo_item :id "<int>") ... ) */

        assume_d(item != NULL, /* void */);
        assume_d(SEXP_listp(item), /* void */);

#if defined(HAVE_ATOMIC_FUNCTIONS)
        local_id = __sync_fetch_and_add(&next_ID, 1);
#else
        if (pthread_mutex_lock(&next_ID_mutex) != 0) {
                dE("Can't lock the next_ID_mutex: %u, %s", errno, strerror(errno));
                abort();
        }

        local_id = ++next_ID;

        if (pthread_mutex_unlock(&next_ID_mutex) != 0) {
                dE("Can't unlock the next_ID_mutex: %u, %s", errno, strerror(errno));
                abort();
        }
#endif
        SEXP_string_newf_r(&uniq_id, "1%05u%u", getpid(), local_id);

        name_ref = SEXP_listref_first(item);
        prev_id  = SEXP_list_replace(name_ref, 3, &uniq_id);

        SEXP_free(prev_id);
        SEXP_free_r(&uniq_id);
        SEXP_free(name_ref);

        return;
}
Exemple #8
0
static int oval_probe_cmd_init(oval_pext_t *pext)
{
	if (pext == NULL) {
		return -1;
	}

	if (SEAP_cmd_register(pext->pdtbl->ctx, PROBECMD_OBJ_EVAL, SEAP_CMDREG_USEARG,
                              &oval_probe_cmd_obj_eval, (void *)pext) != 0)
        {
		dE("Can't register command: %s: errno=%u, %s.", "obj_eval", errno, strerror(errno));
		return (-1);
	}

	if (SEAP_cmd_register(pext->pdtbl->ctx, PROBECMD_STE_FETCH, SEAP_CMDREG_USEARG,
			      &oval_probe_cmd_ste_fetch, (void *)pext) != 0) {
		dE("Can't register command: %s: errno=%u, %s.", "ste_fetch", errno, strerror(errno));

		/* FIXME: unregister the first command */

		return (-1);
	}

	return (0);
}
Exemple #9
0
struct oval_record_field *oval_record_field_clone(struct oval_record_field *old_rf)
{
	struct oval_record_field *new_rf;

	switch (old_rf->record_field_type) {
	case OVAL_RECORD_FIELD_STATE:
	{
		struct oval_record_field_STATE *new_rfs, *old_rfs;

		new_rfs = oscap_alloc(sizeof(*new_rfs));
		if (new_rfs == NULL)
			return NULL;

		old_rfs = (struct oval_record_field_STATE *) old_rf;
		new_rfs->operation = old_rfs->operation;
		new_rfs->variable = old_rfs->variable;
		new_rfs->var_check = old_rfs->var_check;
		new_rfs->ent_check = old_rfs->ent_check;
		new_rf = (struct oval_record_field *) new_rfs;
		break;
	}
	case OVAL_RECORD_FIELD_ITEM:
	{
		struct oval_record_field_ITEM *new_rfi, *old_rfi;

		new_rfi = oscap_alloc(sizeof(*new_rfi));
		if (new_rfi == NULL)
			return NULL;

		old_rfi = (struct oval_record_field_ITEM *) old_rf;
		new_rfi->status = old_rfi->status;
		new_rf = (struct oval_record_field *) new_rfi;
		break;
	}
	default:
		dE("Unsupported record field type: %d.\n", old_rf->record_field_type);
		return NULL;
	}

	new_rf->record_field_type = old_rf->record_field_type;
	new_rf->name = oscap_strdup(old_rf->name);
	new_rf->value = oscap_strdup(old_rf->value);
	new_rf->datatype = old_rf->datatype;
	new_rf->mask = old_rf->mask;

	return new_rf;
}
void
HHV4Vector::CalcCov()
{
  m_cov_manually_set = false;

  if (P()>0){
    //NOTE: only dE is used for Cov calculation!
    Double_t dp = E()/P()*dE(); // error propagation p=sqrt(e^2-m^2)
    Double_t dpt = sin(Theta())*dp;

    m_cov_transversal(0,0) = pow(cos(Phi())*dpt,2);
    m_cov_transversal(1,1) = pow(sin(Phi())*dpt,2);
    m_cov_transversal(0,1) = sin(Phi())*cos(Phi())*dpt*dpt;
    m_cov_transversal(1,0) = sin(Phi())*cos(Phi())*dpt*dpt;
  }

}
int oval_probe_session_reset(oval_probe_session_t *sess, struct oval_syschar_model *sysch)
{
        oval_ph_t *ph;

        if ((ph = oval_probe_handler_get(sess->ph, OVAL_SUBTYPE_ALL)) == NULL) {
		dE("No probe handler for OVAL_SUBTYPE_ALL");
		return (-1);
	}

        if (ph->func(OVAL_SUBTYPE_ALL, ph->uptr, PROBE_HANDLER_ACT_RESET) != 0) {
                return(-1);
        }
        if (sysch != NULL)
                sess->sys_model = sysch;

        return(0);
}
Exemple #12
0
struct oval_record_field *oval_record_field_new(oval_record_field_type_t type)
{
	struct oval_record_field *rf;

	switch (type) {
	case OVAL_RECORD_FIELD_STATE:
	{
		struct oval_record_field_STATE *rfs;

		rfs = oscap_alloc(sizeof(*rfs));
		if (rfs == NULL)
			return NULL;

		rfs->operation = OVAL_OPERATION_UNKNOWN;
		rfs->variable = NULL;
		rfs->var_check = OVAL_CHECK_UNKNOWN;
		rfs->ent_check = OVAL_CHECK_UNKNOWN;
		rf = (struct oval_record_field *) rfs;
		break;
	}
	case OVAL_RECORD_FIELD_ITEM:
	{
		struct oval_record_field_ITEM *rfi;

		rfi = oscap_alloc(sizeof(*rfi));
		if (rfi == NULL)
			return NULL;

		rfi->status = SYSCHAR_STATUS_UNKNOWN;
		rf = (struct oval_record_field *) rfi;
		break;
	}
	default:
		dE("Unsupported record field type: %d.\n", type);
		return NULL;
	}

	rf->record_field_type = type;
	rf->name = NULL;
	rf->value = NULL;
	rf->datatype = OVAL_DATATYPE_UNKNOWN;
	rf->mask = 0;

	return rf;
}
static int file_cb (const char *p, const char *f, void *ptr)
{
        char path_buffer[PATH_MAX];
        SEXP_t *item, xattr_name;
        struct cbargs *args = (struct cbargs *) ptr;
        const char *st_path;

        ssize_t xattr_count = -1;
        char   *xattr_buf = NULL;
        size_t  xattr_buflen = 0, i;

	if (f == NULL) {
		st_path = p;
	} else {
		snprintf (path_buffer, sizeof path_buffer, "%s/%s", p, f);
		st_path = path_buffer;
	}

        SEXP_init(&xattr_name);

	do {
		/* estimate the size of the buffer */
		xattr_count = llistxattr(st_path, NULL, 0);

		if (xattr_count == 0)
				return (0);

		if (xattr_count < 0) {
				dI("FAIL: llistxattr(%s, %p, %zu): errno=%u, %s.", errno, strerror(errno));
				return 0;
		}

		/* allocate space for xattr names */
		xattr_buflen = xattr_count;
		xattr_buf    = oscap_realloc(xattr_buf, sizeof(char) * xattr_buflen);

		/* fill the buffer */
		xattr_count = llistxattr(st_path, xattr_buf, xattr_buflen);

		/* check & retry if needed */
	} while (errno == ERANGE);

        if (xattr_count < 0) {
                dI("FAIL: llistxattr(%s, %p, %zu): errno=%u, %s.", errno, strerror(errno));
                oscap_free(xattr_buf);
        }

        /* update lastpath if needed */
        if (!SEXP_emptyp(&gr_lastpath)) {
                if (SEXP_strcmp(&gr_lastpath, p) != 0) {
                        SEXP_free_r(&gr_lastpath);
                        SEXP_string_new_r(&gr_lastpath, p, strlen(p));
                }
        } else
                SEXP_string_new_r(&gr_lastpath, p, strlen(p));

        i = 0;
        /* collect */
        do {
                SEXP_string_new_r(&xattr_name, xattr_buf + i, strlen(xattr_buf +i));

                if (probe_entobj_cmp(args->attr_ent, &xattr_name) == OVAL_RESULT_TRUE) {
                        ssize_t xattr_vallen = -1;
                        char   *xattr_val = NULL;

                        xattr_vallen = lgetxattr(st_path, xattr_buf + i, NULL, 0);
                retry_value:
                        if (xattr_vallen >= 0) {
				// Check possible buffer overflow
				if (sizeof(char) * (xattr_vallen + 1) <= sizeof(char) * xattr_vallen) {
					dE("Attribute is too long.");
					abort();
				}

				// Allocate buffer, '+1' is for trailing '\0'
 				xattr_val    = oscap_realloc(xattr_val, sizeof(char) * (xattr_vallen + 1));

				// we don't want to override space for '\0' by call of 'lgetxattr'
				// we pass only 'xattr_vallen' instead of 'xattr_vallen + 1'
                                xattr_vallen = lgetxattr(st_path, xattr_buf + i, xattr_val, xattr_vallen);

                                if (xattr_vallen < 0 || errno == ERANGE)
                                        goto retry_value;

				xattr_val[xattr_vallen] = '\0';

                                item = probe_item_create(OVAL_UNIX_FILEEXTENDEDATTRIBUTE, NULL,
                                                         "filepath", OVAL_DATATYPE_STRING, f == NULL ? NULL : st_path,
                                                         "path",     OVAL_DATATYPE_SEXP,  &gr_lastpath,
                                                         "filename", OVAL_DATATYPE_STRING, f == NULL ? "" : f,
                                                         "attribute_name", OVAL_DATATYPE_SEXP,   &xattr_name,
                                                         "value",          OVAL_DATATYPE_STRING, xattr_val,
                                                         NULL);

                                oscap_free(xattr_val);
                        } else {
                                dI("FAIL: lgetxattr(%s, %s, NULL, 0): errno=%u, %s.", errno, strerror(errno));

                                item = probe_item_create(OVAL_UNIX_FILEEXTENDEDATTRIBUTE, NULL, NULL);
                                probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);

                                if (xattr_val != NULL)
                                        oscap_free(xattr_val);
                        }

                        probe_item_collect(args->ctx, item); /* XXX: handle ENOMEM */
                }

                SEXP_free_r(&xattr_name);

                /* skip to next name */
                while (i < xattr_buflen && xattr_buf[i] != '\0')
                        ++i;
		++i;
        } while (xattr_buf + i < xattr_buf + xattr_buflen - 1);

        oscap_free(xattr_buf);

        return (0);
}
int routingtable_probe_main(probe_ctx *ctx, void *arg)
{
	SEXP_t *probe_in, *dst_ent;
	FILE *fp;
	char *line_buf;
	size_t line_len;
        struct route_info rt;
        int probe_ret = 0;

	probe_in = probe_ctx_getobject(ctx);
	dst_ent  = probe_obj_getent(probe_in, "destination", 1);

	if (dst_ent == NULL)
		return (PROBE_ENOENT);

        rt.ip_dst_ent = dst_ent;
	line_len = 0;
	line_buf = NULL;
	fp = NULL;

	switch(probe_ent_getdatatype(dst_ent)) {
	  case OVAL_DATATYPE_IPV4ADDR:
	    fp = fopen("/proc/net/route", "r");
            /* Skip the header line */
            if (getline(&line_buf, &line_len, fp) != -1) {
                while(getline(&line_buf, &line_len, fp) != -1) {
                    if (process_line_ip4(line_buf, &rt) != 0)
                        break;
                    if (collect_item(&rt, ctx) != 0)
                        break;
                }
            }

	    if (!feof(fp)) {
	      /* error */
              dE("An error ocured while reading /proc/net/route: %s", strerror(errno));
	    }
	    break;
	  case OVAL_DATATYPE_IPV6ADDR:
	    fp = fopen("/proc/net/ipv6_route", "r");

	    while(getline(&line_buf, &line_len, fp) != -1) {
	      if (process_line_ip6(line_buf, &rt) != 0)
		break;
	      if (collect_item(&rt, ctx) != 0)
		break;
	    }

	    if (!feof(fp)) {
	      /* error */
              dE("An error ocured while reading /proc/net/ipv6_route: %s", strerror(errno));
            }
	    break;
          default:
            probe_ret = EINVAL;
	}

	if (fp != NULL)
	  fclose(fp);
	if (line_buf != NULL)
	  free(line_buf);

	SEXP_free(dst_ent);

	return (probe_ret);
}
int oval_probe_session_sethandler(oval_probe_session_t *sess, oval_subtype_t type, oval_probe_handler_t handler, void *ptr)
{
	dE("Operation not supported");
        return(-1);
}
Exemple #16
0
extern "C" magma_int_t 
magma_sbulge_applyQ_v2(char side, 
                        magma_int_t NE, magma_int_t N, 
                        magma_int_t NB, magma_int_t Vblksiz, 
                        float *dE, magma_int_t ldde, 
                        float *V, magma_int_t ldv, 
                        float *T, magma_int_t ldt, 
                        magma_int_t *info)
{
    //%===========================
    //%   local variables
    //%===========================
    magma_int_t Vm, Vn, mt, nt;
    magma_int_t myrow, mycol, blkj, blki;
    magma_int_t blkid,vpos,tpos;
    magma_int_t firstrow, nbcolinvolvd;
    magma_int_t versionL  = 113;
    magma_int_t versionR  = 92;
    magma_int_t Vchunksiz = 10;
    *info=0;

    /* Quick return */
    if ( NE == 0 ) {
        return MAGMA_SUCCESS;
    }
    if ( N == 0 ) {
        return MAGMA_SUCCESS;
    }
    if ( NB == 0 ) {
        return MAGMA_SUCCESS;
    }
    /* ==========================================
     * some infos for developer 
     * Initialisation and checking nb of cores
     * ==========================================*/
    /* we have 2 algo for left (113 114) and 2 algo for right (91 92)
     * which correspond to versionL versionR.
     * They are very similar (detail explained in tech report and matlab code)
     * however version 114 and 92 improve locality.
     * while version 113 is used in case WNATZ=1 (construct Q2) which allow 
     * the construction to be done in an optimized way taking into 
     * consideration that the matrix is Identity so making less flops.
     * 
    */

    // Initialize streaming and events
    cudaDeviceSynchronize();
    magma_queue_t cstream;
    magmablasGetKernelStream(&cstream);

    magma_queue_t stream[2];
    magma_queue_create( &stream[0] );
    magma_queue_create( &stream[1] );

    magma_event_t myevent[2];
    cudaEventCreateWithFlags(&myevent[0],cudaEventDisableTiming);
    cudaEventCreateWithFlags(&myevent[1],cudaEventDisableTiming);



    // Azzam 21/11/2012
    // NOTE THAT dwork was of size 2*NE*Vblksiz+...
    // but I am thinking why not modifing it to NE*Vblksiz+...
    // BUT NO because the 2* is used because of making 2 streams working and so 
    // they might be using dwork in parallel
    float *dwork, *dwork0, *dwork1, *dwvt0, *dwvt1;
    float *dT0, *dV0, *dT1, *dV1;
    magma_int_t lddv = ldv;
    magma_int_t lddt = ldt; 
    magma_int_t lddw = 0;
    magma_int_t lddwork  = ((NE+31)/32)*32;
    magma_int_t dwVTsiz  = lddv*Vblksiz; // lddv*lddv + lddv*lddwork;(v2) // lddv*Vblksiz; (v1,v3)
    magma_int_t dworksiz = lddwork*Vblksiz;  // lddv*Vblksiz; (v2)   // NE*Vblksiz=lddwork*Vblksiz; (v1,v3)

    if(MAGMA_SUCCESS != magma_smalloc( &dwork, 2*dworksiz + 2*dwVTsiz +  2*Vchunksiz* (Vblksiz* (lddv+lddt)) )) {
       printf ("!!!!  magma_sbulge_applyQ magma_alloc failed for: dwork\n" );
       exit(-1);
    }
    dwork0 = dwork;               // size = dworksiz;
    dwork1 = dwork0 + dworksiz;   // size = dworksiz;
    dwvt0  = dwork + 2*dworksiz;  // size = dwVTsiz;
    dwvt1  = dwvt0 + dwVTsiz;     // size = dwVTsiz;
    dV0    = dwork + 2*dworksiz + 2*dwVTsiz;
    dT0    = dV0 + Vchunksiz*Vblksiz*lddv;
    dV1    = dT0 + Vchunksiz*Vblksiz*lddt;
    dT1    = dV1 + Vchunksiz*Vblksiz*lddv;


    // make overlapped copy
    magma_int_t ncpy = 0;
    magma_int_t copyed=0, copyst=0;
    magma_int_t blkcnt,nothing, mysiz, flip, vld,tld, locpos;
    findVTsiz(N, NB, Vblksiz, &blkcnt, &nothing);

    flip = 0;

    // performance loss if the reflector are applied to a big number of eigenvectors (~10000)
    // => apply the reflectors to blocks of eigenvectors.
    //magma_int_t nr_bl = magma_ceildiv(NE,10000);        //nr of blocks
    magma_int_t sz_bl = NE; //magma_ceildiv(NE,nr_bl*64)*64; //maximum size of blocks (to have blocks of around the same size and multiple of 64)
    magma_int_t ib;                                      //size of current block


    /* SIDE LEFT  meaning apply E = Q*E = (q_1*q_2*.....*q_n) * E ==> so traverse Vs in reverse order (forward) from q_n to q_1
     *            Also E is splitten by row meaning each apply consist in a block of row (horizontal block) */
    /* SIDE RIGHT meaning apply E = E*Q = E * (q_1*q_2*.....*q_n) ==> so tarverse Vs in normal  order (forward) from q_1 to q_n
     *            Also E is splitten by col meaning each apply consist in a block of col (vertical block) */

    #ifdef ENABLE_DEBUG
    printf("  APPLY Q_v22 GPU with  N %d, NE %d,  NB %d, Vblksiz %d, versionL %d versionR %d  SIDE %c \n",
           N, NE, NB, Vblksiz, versionL, versionR, side);
    #endif

    /*
     * MagmamaLeft
     */
    if(side=='L'){
        /*
         * Version 113:
         * loop over the block_col (nt) and for each find the 
         * number of tiles (mt) in this block_col. then loop over mt, find 
         * the size of the V's(Vm,Vn) and apply it to the corresponding
         * portion of E. 
         */
        if( versionL == 113 ) {
            nt  = magma_ceildiv((N-1),Vblksiz);
            for (blkj=nt-1; blkj>=0; blkj--) {
                /* the index of the first row on the top of block (blkj) */ 
                firstrow = blkj * Vblksiz + 1;
                /*find the number of tile for this block */
                if( blkj == nt-1 )
                    mt = magma_ceildiv( N -  firstrow,    NB);
                else
                    mt = magma_ceildiv( N - (firstrow+1), NB);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blki=mt; blki>0; blki--) {
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow     = firstrow + (mt-blki)*NB;
                    mycol     = blkj*Vblksiz;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if( ( blkj == nt-1 ) && ( blki == mt ) ){
                        Vn = min (Vblksiz, Vm);
                    } else {
                        Vn = min (Vblksiz, Vm-1);
                    }
                    /*calculate the pointer to the Vs and the Ts.
                     * Note that Vs and Ts have special storage done
                     * by the bulgechasing function*/
                    //printf("voici blkj %d blki %d  Vm %d  Vn %d mycol %d vpos %d \n",blkj,blki,Vm, Vn,mycol,vpos);
                    magma_bulge_findpos113(N, NB, Vblksiz, mycol, myrow, &blkid);
               
                    // COPY Vchunksiz Vs and Vchunksiz Ts to GPU and store it in dV0/dV1 and dT0/dT1
                    if(ncpy==0){
                        // flip = 1 for this.
                        copyst = 0;                             // meaning that copy will start copying from blkid =copyst
                        copyed = min(copyst+Vchunksiz, blkcnt); // meaning that copy will end copying at blkid =copyed-1==> next copy had to start at copyed
                        mysiz  = copyed-copyst;                 // the size of the chunk to be copied
                        if(mysiz>0){        
                            ncpy = 1;
                            flip = 1;
                            vpos = copyst*Vblksiz*ldv;
                            tpos = copyst*Vblksiz*ldt;
                            vld  = mysiz * ldv;
                            tld  = mysiz * ldt;
                            magmablasSetKernelStream(stream[1]);
                            magma_ssetmatrix_async(vld, Vblksiz, V(vpos), vld, dV1, vld, stream[1]);
                            magma_ssetmatrix_async(tld, Vblksiz, T(tpos), tld, dT1, tld, stream[1]);
                            //printf("doing the first copy   of mysiz %2d copyst %2d copyed %2d vpos %8d tpos %8d into dV1 dT1\n",mysiz,copyst,copyed,vpos,tpos);
                        }
                    }
                   
                    if(blkid == copyst){
                        flip   = ncpy % 2;
                        copyst = copyed;                             // meaning that copy will start copying from blkid =copyst
                        copyed = min(copyst+Vchunksiz, blkcnt); // meaning that copy will end copying at blkid =copyed-1==> next copy had to start at copyed
                        mysiz  = copyed-copyst;                 // the size of the chunk to be copied
                        //printf(" get to copy blkid %d blkid+(2*Vchunksiz) %d copyst %d copyed %d\n",blkid,blkid+(Vchunksiz),copyst,copyed);
                        if(mysiz>0){              
                            ncpy = ncpy + 1;        
                            vpos = copyst*Vblksiz*ldv;
                            tpos = copyst*Vblksiz*ldt;
                            vld  = mysiz * ldv;
                            tld  = mysiz * ldt;
                            if(flip==0){ // now I am working on dV0 so copy the next and put it on dV1
                                //printf("doing overlapping copy of mysiz %2d copyst %2d copyed %2d vpos %8d tpos %8d into dV1 dT1\n",mysiz,copyst,copyed,vpos,tpos);  
                                magmablasSetKernelStream(stream[1]);   
                                magma_ssetmatrix_async(vld, Vblksiz, V(vpos), vld, dV1, vld, stream[1]);
                                magma_ssetmatrix_async(tld, Vblksiz, T(tpos), tld, dT1, tld, stream[1]);
                            }else{ // now I am working on dV1 so copy the next and put it on dV0
                                //printf("doing overlapping copy of mysiz %2d copyst %2d copyed %2d vpos %8d tpos %8d into dV0 dT0\n",mysiz,copyst,copyed,vpos,tpos);   
                                magmablasSetKernelStream(stream[0]);  
                                magma_ssetmatrix_async(vld, Vblksiz, V(vpos), vld, dV0, vld, stream[0]);
                                magma_ssetmatrix_async(tld, Vblksiz, T(tpos), tld, dT0, tld, stream[0]);
                            }
                        }
                    }

                    if((Vm>0)&&(Vn>0)){
                        locpos = blkid%Vchunksiz;
                        magma_int_t lcvpos   = locpos*Vblksiz*lddv;
                        magma_int_t lctpos   = locpos*Vblksiz*lddt;
                        //printf("voici blkj %d blki %d  Vm %d  Vn %d mycol %d locvpos %5d loctpos %5d  blkid %2d  using data in dV%1d dT%1d \n",blkj,blki,Vm, Vn,mycol,lcvpos,lctpos, blkid,flip,flip);
                        if(flip==0){
                            magmablasSetKernelStream(stream[0]);
                            cudaStreamWaitEvent(stream[0], myevent[1], 0);
                            for(magma_int_t i=0; i<NE; i+= sz_bl){
                                ib = min(sz_bl, NE-i);
                                lddw = min(lddwork,sz_bl);
                                //magma_slarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV0+lcvpos, lddv, dT0+lctpos, lddt, dE(myrow,i), ldde, dwork0, lddw);
                                magma_slarfb_gpu_gemm( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV0+lcvpos, lddv, dT0+lctpos, lddt, dE(myrow,i), ldde, dwork0, lddw, dwvt0, lddv);
                            }
                            cudaEventRecord(myevent[0], stream[0]);
                        }else{
                            magmablasSetKernelStream(stream[1]);
                            cudaStreamWaitEvent(stream[1], myevent[0], 0);
                            for(magma_int_t i=0; i<NE; i+= sz_bl){
                                ib = min(sz_bl, NE-i);
                                lddw = min(lddwork,sz_bl);
                                //magma_slarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV1+lcvpos, lddv, dT1+lctpos, lddt, dE(myrow,i), ldde, dwork1, lddw);
                                magma_slarfb_gpu_gemm( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV1+lcvpos, lddv, dT1+lctpos, lddt, dE(myrow,i), ldde, dwork1, lddw, dwvt1, lddv);
                            }
                            cudaEventRecord(myevent[1], stream[1]);
                        }
                    }  // end for (Vm &Vn) > 0   
                } // end for blki
            } // end for blkj
        } // end if version=113
        /*
         * Version 114:
         * loop over the block_row (mt) and for each find diagonally the 
         * number of tiles (nt) in this block_row. then loop over nt, find 
         * the size of the V's(Vm,Vn) and apply it to the corresponding
         * portion of E. 
         */
        else {
            mt    = magma_ceildiv((N-1),NB);
            for (blki = mt; blki>0; blki--) {
                /* nbcolinvolvd = number of column corresponding to this block_row (blki) */
                nbcolinvolvd = min(N-1, blki*NB);
                /*find the number of tile for this block (diagonal row of tiles) */
                nt = magma_ceildiv(nbcolinvolvd,Vblksiz);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blkj = nt-1; blkj>=0; blkj--) {
                    /* the index of the first row of the first col meaning 
                     * the block on the top left (blki) */ 
                    firstrow = (mt-blki)*NB+1;                
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow    = firstrow + blkj*Vblksiz;
                    mycol    = blkj*Vblksiz;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if( ( blkj == nt-1 ) && ( blki == mt ) ){
                        Vn = min (Vblksiz, Vm);
                    }else{
                        Vn = min (Vblksiz, Vm-1);
                    }

                    if((Vm>0)&&(Vn>0)){
                    /*calculate the pointer to the Vs and the Ts.
                     * Note that Vs and Ts have special storage done
                     * by the bulgechasing function*/
                        magma_bulge_findVTpos(N, NB, Vblksiz, mycol, myrow, ldv, ldt, &vpos, &tpos);
                        magma_ssetmatrix_async(Vm, Vn, V(vpos), ldv, dV0, lddv, NULL);
                        magma_ssetmatrix_async(Vn,  Vn, T(tpos), ldt, dT0, lddt, NULL);
                        //printf("voici blki %d  rownbm %d mycol %d  coled %d  blkid %d vpos %d  tpos %d\n", blki, rownbm, mycol, coled, blkid, vpos, tpos);
                        for(magma_int_t i=0; i<NE; i+= sz_bl){
                            ib = min(sz_bl, NE-i);
                            magma_slarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV0, lddv, dT0, lddt, dE(myrow,i), ldde, dwork, NE);
                        }
                    } // end for (Vm &Vn) > 0
                } // end for blkj
            } // end for blki
        } // end version 114
    } // end LEFT
    /*
     * MagmaRight
     */
    else {
        /*
         * Version 91:
         */
        if( versionR == 91 ) {
            nt  = magma_ceildiv((N-1),Vblksiz);
            for (blkj=0; blkj<nt; blkj++) {
                /* the index of the first myrow on the top of block (blkj) */ 
                firstrow = blkj * Vblksiz + 1;
                /*find the number of tile for this block */
                if( blkj == nt-1 )
                    mt = magma_ceildiv( N -  firstrow,    NB);
                else
                    mt = magma_ceildiv( N - (firstrow+1), NB);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blki=1; blki<=mt; blki++) {
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow  = firstrow + (mt-blki)*NB;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if( ( blkj == nt-1 ) && ( blki == mt ) )
                    {
                        Vn = min (Vblksiz, Vm);
                    }else{
                        Vn = min (Vblksiz, Vm-1);
                    }
                    mycol     = blkj*Vblksiz;
                    if((Vm>0)&&(Vn>0)){
                        /*calculate the pointer to the Vs and the Ts.
                         * Note that Vs and Ts have special storage done
                         * by the bulgechasing function*/
                        magma_bulge_findVTpos(N, NB, Vblksiz ,mycol, myrow, ldv, ldt, &vpos, &tpos);
                        magma_ssetmatrix_async(Vm, Vn, V(vpos), ldv, dV0, lddv, NULL);
                        magma_ssetmatrix_async(Vn,  Vn, T(tpos), ldt, dT0, lddt, NULL);
                        magma_slarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, NE, Vm, Vn, dV0, lddv, dT0, lddt, dE(0, myrow), ldde, dwork, NE);
                    } // end for (Vm &Vn) > 0
                } // end for blki
            } // end fo blkj
        } // end of version 91
        /*
         * Version 92:
         */
        else {
            mt    = magma_ceildiv((N-1),NB);
            for (blki = 1; blki<=mt; blki++) {
                /* nbcolinvolvd = number of column corresponding to this block_row (blki) */
                nbcolinvolvd = min(N-1, blki*NB);
                /*find the number of tile for this block (diagonal row of tiles) */
                nt = magma_ceildiv(nbcolinvolvd,Vblksiz);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blkj = 0; blkj<nt; blkj++) {
                    /* the index of the first row of the first col meaning 
                     * the block on the top left (blki) */ 
                    firstrow = (mt-blki)*NB+1;                
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow    = firstrow + blkj*Vblksiz;
                    mycol    = blkj*Vblksiz;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if( ( blkj == nt-1 ) && ( blki == mt ) ){
                        Vn = min (Vblksiz, Vm);
                    }else{
                        Vn = min (Vblksiz, Vm-1);
                    }
                    if((Vm>0)&&(Vn>0)){
                        /*calculate the pointer to the Vs and the Ts.
                         * Note that Vs and Ts have special storage done
                         * by the bulgechasing function*/
                        magma_bulge_findVTpos(N, NB, Vblksiz ,mycol, myrow, ldv, ldt, &vpos, &tpos);
                        magma_ssetmatrix_async(Vm, Vn, V(vpos), ldv, dV0, lddv, NULL);
                        magma_ssetmatrix_async(Vn,  Vn, T(tpos), ldt, dT0, lddt, NULL);
                        magma_slarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, NE, Vm, Vn, dV0, lddv, dT0, lddt, dE(0, myrow), ldde, dwork, NE);
                    } // end for (Vm &Vn) > 0
                } //end for blkj
            } // end for blki
        } //end of version 92
    } // end RIGHT


    cudaDeviceSynchronize();
    magmablasSetKernelStream(cstream);        
    cudaEventDestroy(myevent[0]);
    cudaEventDestroy(myevent[1]);
    magma_queue_destroy( stream[0] );
    magma_queue_destroy( stream[1] );
    magma_free(dwork);


    return MAGMA_SUCCESS;
}
void
HHV4Vector::PrintErrors() const
{
  std::cout << Name() << "  ";
  Printf(" (Errors)    %8.2f  %8.4f  %8.4f  ", dE(), dEta(), dPhi());
}
Exemple #18
0
static int oval_varref_attr_to_sexp(void *sess, struct oval_entity *entity, struct oval_syschar *syschar, SEXP_t **out_sexp)
{
	unsigned int val_cnt = 0;
	SEXP_t *val_lst, *val_sexp, *varref, *id_sexp, *val_cnt_sexp;
	oval_datatype_t dt;
	struct oval_variable *var;
	struct oval_value_iterator *vit;
	struct oval_value *val;
	oval_syschar_collection_flag_t flag;
	char msg[100];
	int ret = 0;

	var = oval_entity_get_variable(entity);
	if (oval_probe_query_variable(sess, var) != 0) {
		dE("Can't convert variable reference to SEXP.");
		return -1;
	}

	flag = oval_variable_get_collection_flag(var);
	switch (flag) {
	case SYSCHAR_FLAG_COMPLETE:
	case SYSCHAR_FLAG_INCOMPLETE:
		vit = oval_variable_get_values(var);
		if (oval_value_iterator_has_more(vit))
			break;
		oval_value_iterator_free(vit);
		/* fall through */
	case SYSCHAR_FLAG_DOES_NOT_EXIST:
		snprintf(msg, sizeof(msg), "Referenced variable has no values (%s).", oval_variable_get_id(var));
		dI("%s", msg);
		ret = 1;
		break;
	default:
		snprintf(msg, sizeof(msg), "There was a problem processing referenced variable (%s).", oval_variable_get_id(var));
		dW("%s", msg);
		ret = 1;
	}

	if (ret) {
		oval_syschar_add_new_message(syschar, msg, OVAL_MESSAGE_LEVEL_WARNING);
		oval_syschar_set_flag(syschar, SYSCHAR_FLAG_DOES_NOT_EXIST);
		return ret;
	}

	val_lst = SEXP_list_new(NULL);

	while (oval_value_iterator_has_more(vit)) {
		val = oval_value_iterator_next(vit);

		dt = oval_entity_get_datatype(entity);
		val_sexp = oval_value_to_sexp(val, dt);
		if (val_sexp == NULL) {
			oval_syschar_add_new_message(syschar, "Failed to convert variable value.", OVAL_MESSAGE_LEVEL_ERROR);
			oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR);
			SEXP_free(val_lst);
			oval_value_iterator_free(vit);
			return -1;
		}

		SEXP_list_add(val_lst, val_sexp);
		SEXP_free(val_sexp);
		++val_cnt;
	}
	oval_value_iterator_free(vit);

	id_sexp = SEXP_string_newf("%s", oval_variable_get_id(var));
	val_cnt_sexp = SEXP_number_newu(val_cnt);

	varref = SEXP_list_new(id_sexp, val_cnt_sexp, val_lst, NULL);

	SEXP_free(id_sexp);
	SEXP_free(val_cnt_sexp);
	SEXP_free(val_lst);

	*out_sexp = varref;
	return 0;
}
Exemple #19
0
void *probe_worker_runfn(void *arg)
{
	probe_pwpair_t *pair = (probe_pwpair_t *)arg;

	SEXP_t *probe_res, *obj, *oid;
	int     probe_ret;

#if defined(HAVE_PTHREAD_SETNAME_NP)
	pthread_setname_np(pthread_self(), "probe_worker");
#endif
	dD("handling SEAP message ID %u", pair->pth->sid);
	//
	probe_ret = -1;
	probe_res = pair->pth->msg_handler(pair->probe, pair->pth->msg, &probe_ret);
	//
	dD("handler result = %p, return code = %d", probe_res, probe_ret);

	/* Assuming that the red-black tree API is doing locking for us... */
	if (rbt_i32_del(pair->probe->workers, pair->pth->sid, NULL) != 0) {
		dW("thread not found in the probe thread tree, probably canceled by an external signal");
		/*
		 * XXX: this is a possible deadlock; we can't send anything from
		 * here because the signal handler replied to the message
		 */
		arg = NULL;

                SEAP_msg_free(pair->pth->msg);
                SEXP_free(probe_res);
                oscap_free(pair);

                return (NULL);
	} else {
                SEXP_t *items;

		dD("probe thread deleted");

		obj = SEAP_msg_get(pair->pth->msg);
		oid = probe_obj_getattrval(obj, "id");
                items = probe_cobj_get_items(probe_res);

                if (items != NULL) {
                        SEXP_list_sort(items, SEXP_refcmp);
                        SEXP_free(items);
                }

		if (probe_rcache_sexp_add(pair->probe->rcache, oid, probe_res) != 0) {
			/* TODO */
			abort();
		}

		SEXP_vfree(obj, oid, NULL);
	}

	if (probe_ret != 0) {
		/*
		 * Something bad happened. A hint of the cause is stored as a error code in
		 * probe_ret (should be). We'll send it to the library using a SEAP error packet.
		 */
		if (SEAP_replyerr(pair->probe->SEAP_ctx, pair->probe->sd, pair->pth->msg, probe_ret) == -1) {
			int ret = errno;

			dE("An error ocured while sending error status. errno=%u, %s.", errno, strerror(errno));
			SEXP_free(probe_res);

			/* FIXME */
			exit(ret);
		}
		SEXP_free(probe_res);
	} else {
		SEAP_msg_t *seap_reply;
		/*
		 * OK, the probe actually returned something, let's send it to the library.
		 */
		seap_reply = SEAP_msg_new();
		SEAP_msg_set(seap_reply, probe_res);

		if (SEAP_reply(pair->probe->SEAP_ctx, pair->probe->sd, seap_reply, pair->pth->msg) == -1) {
			int ret = errno;

			SEAP_msg_free(seap_reply);
			SEXP_free(probe_res);

			exit(ret);
		}

		SEAP_msg_free(seap_reply);
                SEXP_free(probe_res);
	}

        SEAP_msg_free(pair->pth->msg);
        oscap_free(pair->pth);
	oscap_free(pair);
	pthread_detach(pthread_self());

	return (NULL);
}
Exemple #20
0
extern "C" void magma_zbulge_applyQ(
    magma_int_t WANTZ, magma_side_t SIDE, magma_int_t NE, magma_int_t N, magma_int_t NB,
    magma_int_t Vblksiz, magmaDoubleComplex *E, magma_int_t LDE,
    magmaDoubleComplex *V, magmaDoubleComplex *TAU, magmaDoubleComplex *T,
    magma_int_t *INFO, magmaDoubleComplex *dV, magmaDoubleComplex *dT,
    magmaDoubleComplex *dE, magma_int_t copytype )
{
    //%===========================
    //%   local variables
    //%===========================
    magmaDoubleComplex c_zero = MAGMA_Z_ZERO;
    magmaDoubleComplex c_one  = MAGMA_Z_ONE;
    
    magma_int_t LDT, LDV, firstcolj;
    magma_int_t bg, nbGblk, rownbm, k, m, n;
    magma_int_t st, ed, fst, vlen, vnb, colj, len;
    magma_int_t blkid, vpos, taupos, tpos;
    //magmaDoubleComplex *WORK;
    magma_int_t LWORK;
    magma_int_t  cur_blksiz, avai_blksiz, ncolinvolvd;
    magma_int_t  nbgr, colst, coled, versionL, versionR;
    magma_int_t blkcnt=-1;

    magma_queue_t orig_stream;
    magmablasGetKernelStream( &orig_stream );
    
    *INFO=0;
    versionL = 113;
    versionR = 92;
    LDT      = Vblksiz;
    LDV      = NB+Vblksiz-1;
    //blklen = LDV*Vblksiz;
    nbGblk   = plasma_ceildiv((N-1), Vblksiz);
    //magma_zmalloc_cpu( &WORK, LWORK );

    /* find the size of the matrix T V*/
    findVTsiz(N, NB, Vblksiz, &blkcnt, &LDV);
    /* Copy E & V & T to the GPU in dE and dV and dT
     * depending on copytype:
     * 1: mean copy only V
     * 2: mean copy V and T
     * 3: mean copy V, T and E
     * */
    if (copytype > 0) magma_zsetmatrix( LDV, blkcnt*Vblksiz, V, LDV, dV, LDV );
    if (copytype > 1) magma_zsetmatrix( LDT, blkcnt*Vblksiz, T, LDT, dT, LDT );
    if (copytype > 2) magma_zsetmatrix( N, NE, E, N, dE, N );
    magmaDoubleComplex *dwork;
    //ldwork  = NE;
    LWORK   = 2*N*max(Vblksiz, 64);
    if (MAGMA_SUCCESS != magma_zmalloc( &dwork, LWORK )) {
        printf ("!!!!  magma_zbulge_applyQ magma_alloc failed for: dwork\n" );
        exit(-1);
    }

    /* SIDE LEFT  meaning apply E = Q*E = (q_1*q_2*.....*q_n) * E ==> so traverse Vs in reverse order (forward) from q_n to q_1
     *            Also E is splitten by row meaning each apply consist in a block of row (horizontal block) */
    /* SIDE RIGHT meaning apply E = E*Q = E * (q_1*q_2*.....*q_n) ==> so tarverse Vs in normal  order (forward) from q_1 to q_n
     *            Also E is splitten by col meaning each apply consist in a block of col (vertical block) */

    /* WANTZ = 1 meaning E is IDENTITY so form Q using optimized update.
     *         So we use the reverse order from small q to large one,
     *         so from q_n to q_1 so Left update to Identity.
     *         Use versionL 113 because in 114 we need to update the whole matrix and not in icreasing order.
     * WANTZ = 2 meaning E is a full matrix and need to be updated from Left or Right so use normal update
     * */
    if (WANTZ == 1) {
        versionL=113;
        SIDE = MagmaLeft;
        //set the matrix to Identity here to avoid copying it from the CPU
        magmablas_zlaset( MagmaFull, N, N, c_zero, c_one, dE, N );
    }
    


    printf("  APPLY Q_v115 GPU with  N %d   NB %d   Vblksiz %d SIDE %c versionL %d versionR %d WANTZ %d \n",
           (int) N, (int) NB, (int) Vblksiz, SIDE, (int) versionL, (int) versionR, (int) WANTZ);


#if defined(USESTREAM)
    magma_int_t N2=N/2;
    magma_int_t N1=N-N2;
    printf("using stream\n");
    magma_queue_t stream[2];
    magma_queue_create( &stream[0] );
    magma_queue_create( &stream[1] );
#endif
    

    if (SIDE == MagmaLeft) {
        if (versionL == 113) {
            for (bg = nbGblk; bg > 0; bg--) {
                firstcolj = (bg-1)*Vblksiz + 1;
                if (bg == nbGblk)
                    rownbm = plasma_ceildiv((N-(firstcolj)), NB);  // last blk has size=1 used for complex to handle A(N,N-1)
                else
                    rownbm = plasma_ceildiv((N-(firstcolj+1)), NB);
                
                for (m = rownbm; m > 0; m--) {
                    vlen = 0;
                    vnb  = 0;
                    colj = (bg-1)*Vblksiz; // for k=0; I compute the fst and then can remove it from the loop
                    fst  = (rownbm -m)*NB+colj +1;
                    for (k=0; k < Vblksiz; k++) {
                        colj = (bg-1)*Vblksiz + k;
                        st   = (rownbm -m)*NB+colj +1;
                        ed   = min(st+NB-1, N-1);
                        if (st > ed) break;
                        if ((st == ed) && (colj != N-2)) break;
                        vlen=ed-fst+1;
                        vnb=k+1;
                    }
                    colst     = (bg-1)*Vblksiz;
                    findVTpos(N, NB, Vblksiz, colst, fst, &vpos, &taupos, &tpos, &blkid);
                    printf("voici bg %d m %d  vlen %d  vnb %d fcolj %d vpos %d taupos %d \n", (int) bg, (int) m, (int) vlen, (int) vnb, (int) colst+1, (int) vpos+1, (int) taupos+1);
                    if ((vlen > 0) && (vnb > 0)) {
                        if (WANTZ == 1) {
                            len =  N-colst;
                            magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, vlen, len, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(fst,colst), LDE, dwork, len);
                        } else {
                            magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, vlen, NE, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(fst,0), LDE, dwork, NE);
                        }
                    }
                }
            }
        } else if (versionL == 114) {
            rownbm = plasma_ceildiv((N-1), NB);
            for (m = rownbm; m > 0; m--) {
                ncolinvolvd = min(N-1, m*NB);
                avai_blksiz=min(Vblksiz, ncolinvolvd);
                nbgr = plasma_ceildiv(ncolinvolvd, avai_blksiz);
                for (n = nbgr; n > 0; n--) {
                    vlen = 0;
                    vnb  = 0;
                    cur_blksiz = min(ncolinvolvd-(n-1)*avai_blksiz, avai_blksiz);
                    colst = (n-1)*avai_blksiz;
                    coled = colst + cur_blksiz -1;
                    fst   = (rownbm -m)*NB+colst +1;
                    for (colj=colst; colj <= coled; colj++) {
                        st = (rownbm -m)*NB+colj +1;
                        ed = min(st+NB-1, N-1);
                        if (st > ed) break;
                        if ((st == ed) && (colj != N-2)) break;
                        vlen=ed-fst+1;
                        vnb=vnb+1;
                    }
                    findVTpos(N, NB, Vblksiz, colst, fst, &vpos, &taupos, &tpos, &blkid);
                    //printf("voici bg %d m %d  vlen %d  vnb %d fcolj %d vpos %d taupos %d \n", bg, m, vlen, vnb, colst+1, vpos+1, taupos+1);
                    if ((vlen > 0) && (vnb > 0)) {
                        #if defined(USESTREAM)
                        magmablasSetKernelStream(stream[0]);
                        magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, vlen, N1, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(fst,0), LDE, dwork, N1);
                        magmablasSetKernelStream(stream[1]);
                        magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, vlen, N2, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(fst,N1), LDE, &dwork[N1*Vblksiz], N2);
                        #else
                        magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, vlen, NE, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(fst,0), LDE, dwork, NE);
                        #endif
                    }
                }
            }
        }
    } else if (SIDE == MagmaRight) {
        if (versionR == 91) {
            for (bg =1; bg <= nbGblk; bg++) {
                firstcolj = (bg-1)*Vblksiz + 1;
                rownbm    = plasma_ceildiv((N-(firstcolj+1)), NB);
                if (bg == nbGblk) rownbm    = plasma_ceildiv((N-(firstcolj)), NB);  // last blk has size=1 used for complex to handle A(N,N-1)
                for (m = 1; m <= rownbm; m++) {
                    vlen = 0;
                    vnb  = 0;
                    // for k=0; I compute the fst and then can remove it from the loop
                    colj = (bg-1)*Vblksiz;
                    fst  = (rownbm -m)*NB+colj +1;
                    for (k=0; k < Vblksiz; k++) {
                        colj = (bg-1)*Vblksiz + k;
                        st   = (rownbm -m)*NB+colj +1;
                        ed   = min(st+NB-1, N-1);
                        if (st > ed) break;
                        if ((st == ed) && (colj != N-2)) break;
                        vlen=ed-fst+1;
                        vnb=k+1;
                    }
                    colj     = (bg-1)*Vblksiz;
                    findVTpos(N, NB, Vblksiz, colj, fst, &vpos, &taupos, &tpos, &blkid);
                    //printf("voici bg %d m %d  vlen %d  vnb %d fcolj %d vpos %d taupos %d \n", bg, m, vlen, vnb, colj, vpos, taupos);
                    if ((vlen > 0) && (vnb > 0)) {
                        #if defined(USESTREAM)
                        magmablasSetKernelStream(stream[0]);
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, N1, vlen, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(0, fst), LDE, dwork, N1);
                        magmablasSetKernelStream(stream[1]);
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, N2, vlen, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(N1, fst), LDE, &dwork[N1*Vblksiz], N2);
                        #else
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, NE, vlen, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(0, fst), LDE, dwork, NE);
                        #endif
                    }
                }
            }
        } else if (versionR == 92) {
            rownbm = plasma_ceildiv((N-1), NB);
            for (m = 1; m <= rownbm; m++) {
                ncolinvolvd = min(N-1, m*NB);
                avai_blksiz=min(Vblksiz, ncolinvolvd);
                nbgr = plasma_ceildiv(ncolinvolvd, avai_blksiz);
                for (n = 1; n <= nbgr; n++) {
                    vlen = 0;
                    vnb  = 0;
                    cur_blksiz = min(ncolinvolvd-(n-1)*avai_blksiz, avai_blksiz);
                    colst = (n-1)*avai_blksiz;
                    coled = colst + cur_blksiz -1;
                    fst   = (rownbm -m)*NB+colst +1;
                    for (colj=colst; colj <= coled; colj++) {
                        st = (rownbm -m)*NB+colj +1;
                        ed = min(st+NB-1, N-1);
                        if (st > ed) break;
                        if ((st == ed) && (colj != N-2)) break;
                        vlen=ed-fst+1;
                        vnb=vnb+1;
                    }
                    findVTpos(N, NB, Vblksiz, colst, fst, &vpos, &taupos, &tpos, &blkid);
                    if ((vlen > 0) && (vnb > 0)) {
                        #if defined(USESTREAM)
                        magmablasSetKernelStream(stream[0]);
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, N1, vlen, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(0, fst), LDE, dwork, N1);
                        magmablasSetKernelStream(stream[1]);
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, N2, vlen, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(N1, fst), LDE, &dwork[N1*Vblksiz], N2);
                        #else
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, NE, vlen, vnb, dV(vpos), LDV, dT(tpos), LDT, dE(0, fst), LDE, dwork, NE);
                        #endif
                    }
                }
            }
        }
    } else {
            printf("ERROR SIDE %d\n", SIDE);
    }

#if defined(USESTREAM)
    magma_queue_destroy( stream[0] );
    magma_queue_destroy( stream[1] );
#endif
    magmablasSetKernelStream( orig_stream );
}
Exemple #21
0
ssize_t strbuf_write (strbuf_t *buf, int fd)
{
        struct strblk *cur;
        ssize_t rsize, wsize;

        struct iovec  *iov;
        int            ioc; /* helper/index */
	int            iot; /* total number of buffers */
	int            iow; /* total number of buffer that will be passed to the next writev */

	rsize = 0;
	iov   = NULL;
        cur   = buf->beg;
	iot   = (buf->size / buf->blkmax) + 1;

	dI("total I/O vectors = %d\n", iot);

	while (iot > 0) {
		/*
		 * Prepare I/O vector
		 */
		if (iot > IOV_MAX) {
			dI("iot (%d) > IOV_MAX (%d)\n", iot, IOV_MAX);
			iow  = IOV_MAX;
			iot -= IOV_MAX;
		} else {
			dI("iot (%d) < IOV_MAX (%d)\n", iot, IOV_MAX);
			iow  = iot;
			iot  = 0;
		}

		iov = realloc (iov, sizeof (struct iovec) * iow);
		ioc = 0;

		while (cur != NULL && ioc < iow) {
			iov[ioc].iov_base = cur->data;
			iov[ioc].iov_len  = cur->size;

			++ioc;
			cur = cur->next;
		}

		dI("ioc = %d\n", ioc);

		/*
		 * Write
		 */
		wsize = writev (fd, iov, ioc);

		if (wsize < 0) {
			dE("writev(%d, %p, %d) failed: %u, %s.\n", fd, iov, ioc, errno, strerror (errno));
                        free(iov);
			return (-1);
		}

		rsize += wsize;
	}

        free (iov);
	dI("total bytes written: %zu\n", (size_t)rsize);

        return (rsize);
}
Exemple #22
0
int oval_object_to_sexp(void *sess, const char *typestr, struct oval_syschar *syschar, SEXP_t **out_sexp)
{
	unsigned int ent_cnt, varref_cnt;
	int ret;
	SEXP_t *obj_sexp, *elm, *varrefs, *ent_lst, *lst, *stmp;
	SEXP_t *r0, *r1, *r2, *obj_attr, sm0, sm1;

	struct oval_object *object;
	struct oval_object_content_iterator *cit;
	struct oval_behavior_iterator *bit;
	struct oval_object_content *content;
	struct oval_entity *entity;

	char obj_name[128];
	const char *obj_id;

	object = oval_syschar_get_object(syschar);

	/*
	 * Object name & attributes (id)
	 */
	ret = snprintf(obj_name, sizeof obj_name, "%s_object", typestr);
	if (ret<0 || (unsigned int) ret > sizeof obj_name) {
		dE("obj_name length too short");
		return -1;
	}

	// even though it returns const char* it has to be freed :-(
	char *obj_over = (char*)oval_schema_version_to_cstr(oval_object_get_platform_schema_version(object));
	obj_id   = oval_object_get_id(object);
	obj_attr = probe_attr_creat("id", SEXP_string_new_r(&sm0, obj_id, strlen(obj_id)),
	                            "oval_version", SEXP_string_new_r(&sm1, obj_over, strlen(obj_over)),
	                            NULL);
	free(obj_over);

	obj_sexp = probe_obj_new(obj_name, obj_attr);

	SEXP_free_r(&sm0);
	SEXP_free_r(&sm1);
	SEXP_free(obj_attr);

	/*
	 * Object content
	 */

	ent_lst = SEXP_list_new(NULL);
	varrefs = NULL;
	ent_cnt = varref_cnt = 0;

	cit = oval_object_get_object_contents(object);
	while (oval_object_content_iterator_has_more(cit)) {
		oval_check_t ochk;
		oval_entity_varref_type_t vr_type;

		content = oval_object_content_iterator_next(cit);
		elm = NULL;
		lst = ent_lst;

		switch (oval_object_content_get_type(content)) {
		case OVAL_OBJECTCONTENT_ENTITY:
			entity = oval_object_content_get_entity(content);
			elm = oval_entity_to_sexp(entity);
			if (elm == NULL)
				break;

			ochk = oval_object_content_get_varCheck(content);
			if (ochk != OVAL_CHECK_UNKNOWN) {
				probe_ent_attr_add(elm, "var_check",
						   r0 = SEXP_number_newu_32(ochk));
				SEXP_free(r0);
			}
			ret = 0;
			vr_type = oval_entity_get_varref_type(entity);
			if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE) {
				const char *var_id = oval_variable_get_id(oval_entity_get_variable(entity));
				const char *field_name = oval_object_content_get_field_name(content);
				dI("Object '%s' references variable '%s' in '%s' field.", obj_id, var_id, field_name);
				ret = oval_varref_attr_to_sexp(sess, entity, syschar, &stmp);

				if (ret == 0) {
					if (varrefs == NULL)
						varrefs = SEXP_list_new(NULL);

					SEXP_list_add(varrefs, stmp);
					SEXP_free(stmp);
					// todo: don't add duplicates
					++varref_cnt;

					lst = obj_sexp;
					++ent_cnt;
				}
			} else if (vr_type == OVAL_ENTITY_VARREF_ELEMENT) {
				SEXP_t *val_lst;
				struct oval_variable *var;
				oval_datatype_t dt;

				var = oval_entity_get_variable(entity);
				dt = oval_entity_get_datatype(entity);
				ret = oval_varref_elm_to_sexp(sess, var, dt, &val_lst, syschar);

				if (ret == 0) {
					SEXP_list_add(elm, val_lst);
					SEXP_free(val_lst);
				}
			}

			if (ret != 0) {
				SEXP_t s_flag;
				SEXP_number_newi_32_r(&s_flag, SYSCHAR_FLAG_DOES_NOT_EXIST);
				probe_item_attr_add(obj_sexp, "skip_eval", &s_flag);
				SEXP_free_r(&s_flag);

				SEXP_free(elm);
				SEXP_free(ent_lst);
				if (varrefs != NULL)
					SEXP_free(varrefs);
				oval_object_content_iterator_free(cit);

				*out_sexp = obj_sexp;

				return (0);
			}

			break;

		case OVAL_OBJECTCONTENT_SET:
			elm = oval_set_to_sexp(oval_object_content_get_setobject(content));
			break;

		case OVAL_OBJECTCONTENT_FILTER: {
			struct oval_filter *filter = oval_object_content_get_filter(content);
			struct oval_state *ste = oval_filter_get_state(filter);
			const char *ste_id = oval_state_get_id(ste);
			oval_filter_action_t action = oval_filter_get_filter_action(filter);
			const char *action_text = oval_filter_action_get_text(action);
			dI("Object '%s' has a filter that %ss items conforming to state '%s'.",
					obj_id, action_text, ste_id);
			elm = oval_filter_to_sexp(filter);
			}
			break;

		case OVAL_OBJECTCONTENT_UNKNOWN:
			break;
		}

		if (elm == NULL) {
			SEXP_free(obj_sexp);
			SEXP_free(ent_lst);
			if (varrefs != NULL)
				SEXP_free(varrefs);
			oval_object_content_iterator_free(cit);

			return -1;
		}

		SEXP_list_add(lst, elm);
		SEXP_free(elm);
	}

	if (varrefs != NULL) {
		// todo: SEXP_list_push()
		stmp = SEXP_list_new(r0 = SEXP_string_new("varrefs", 7),
				     r1 = SEXP_number_newu(varref_cnt), r2 = SEXP_number_newu(ent_cnt), NULL);
		SEXP_vfree(r0, r1, r2, NULL);

		r0 = SEXP_list_join(stmp, varrefs);
		SEXP_list_add(obj_sexp, r0);
		SEXP_vfree(stmp, varrefs, r0, NULL);
	}

	stmp = SEXP_list_join(obj_sexp, ent_lst);
	SEXP_free(obj_sexp);
	SEXP_free(ent_lst);
	obj_sexp = stmp;

	oval_object_content_iterator_free(cit);

	/*
	 * Object behaviors
	 */

	bit = oval_object_get_behaviors(object);
	if (oval_behavior_iterator_has_more(bit)) {
		elm = oval_behaviors_to_sexp(bit);
		SEXP_list_add(obj_sexp, elm);
		SEXP_free(elm);
	}
	oval_behavior_iterator_free(bit);

	*out_sexp = obj_sexp;

	return (0);
}
oval_result_t oval_ipaddr_cmp(int af, const char *s1, const char *s2, oval_operation_t op)
{
	oval_result_t result = OVAL_RESULT_ERROR;
	uint32_t mask1 = 0, mask2 = 0;
	char addr1[INET6_ADDRSTRLEN];
	char addr2[INET6_ADDRSTRLEN];

	if (ipaddr_parse(af, s1, &mask1, &addr1) || ipaddr_parse(af, s2, &mask2, &addr2)) {
		return result;
	}

	switch (op) {
	case OVAL_OPERATION_EQUALS:
		if (!ipaddr_cmp(af, &addr1, &addr2) && mask1 == mask2)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	case OVAL_OPERATION_NOT_EQUAL:
		if (ipaddr_cmp(af, &addr1, &addr2) || mask1 != mask2)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	case OVAL_OPERATION_SUBSET_OF:
		/* This asserts that every IP address in the set of IP addresses
		 * on the system (add2, mask2) must be present in the set of IP
		 * addresses defined in the stated entity (addr1, mask1). */
		if (mask1 > mask2) {
			/* The bigger the netmask (IPv4) or prefix-length (IPv6) is
			 * the less IP addresses there are in the range. */
			result = OVAL_RESULT_FALSE;
			break;
		}

		/* Otherwise, compare the first bits defined by mask1 */
		ipaddr_mask(af, &addr1, mask1);
		ipaddr_mask(af, &addr2, mask1);
		if (ipaddr_cmp(af, &addr1, &addr2) == 0)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	case OVAL_OPERATION_GREATER_THAN:
		ipaddr_mask(af, &addr1, mask1);
		ipaddr_mask(af, &addr2, mask2);
		if (ipaddr_cmp(af, &addr1, &addr2) < 0)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	case OVAL_OPERATION_GREATER_THAN_OR_EQUAL:
		ipaddr_mask(af, &addr1, mask1);
		ipaddr_mask(af, &addr2, mask2);
		if (ipaddr_cmp(af, &addr1, &addr2) <= 0)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	case OVAL_OPERATION_SUPERSET_OF:
		/* This asserts that every IP address in the set of IP addresses defined in
		 * the stated entity (addr1, mask1) is present in the set of IP addresses
		 * on the system. (addr2, mask2). */
		if (mask1 < mask2) {
			/* The smaller the netmask (IPv4) or prefix-length (IPv6) is
			 * the more IP addresses there are in the range */
			result = OVAL_RESULT_FALSE;
			break;
		}

		/* Otherwise, compare the first bits defined by mask2 */
		ipaddr_mask(af, &addr1, mask2);
		ipaddr_mask(af, &addr2, mask2);
		if (ipaddr_cmp(af, &addr1, &addr2) == 0)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	case OVAL_OPERATION_LESS_THAN:
		ipaddr_mask(af, &addr1, mask1);
		ipaddr_mask(af, &addr2, mask2);
		if (ipaddr_cmp(af, &addr1, &addr2) > 0)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	case OVAL_OPERATION_LESS_THAN_OR_EQUAL:
		ipaddr_mask(af, &addr1, mask1);
		ipaddr_mask(af, &addr2, mask2);
		if (ipaddr_cmp(af, &addr1, &addr2) >= 0)
			result = OVAL_RESULT_TRUE;
		else
			result = OVAL_RESULT_FALSE;
		break;
	default:
		dE("Unexpected compare operation: %d.\n", op);
		assert(false);
	}

	return result;
}
void *probe_signal_handler(void *arg)
{
        probe_t  *probe = (probe_t *)arg;
	siginfo_t siinf;
	sigset_t  siset;

#if defined(HAVE_PTHREAD_SETNAME_NP)
# if defined(__APPLE__)
	pthread_setname_np("signal_handler");
# else
	pthread_setname_np(pthread_self(), "signal_handler");
# endif
#endif

	sigemptyset(&siset);
	sigaddset(&siset, SIGHUP);
	sigaddset(&siset, SIGUSR1);
	sigaddset(&siset, SIGUSR2);
	sigaddset(&siset, SIGINT);
	sigaddset(&siset, SIGTERM);
	sigaddset(&siset, SIGQUIT);
        sigaddset(&siset, SIGPIPE);

#if defined(__linux__)
        if (prctl(PR_SET_PDEATHSIG, SIGTERM) != 0)
                dW("prctl(PR_SET_PDEATHSIG, SIGTERM) failed");
#endif
       
	dD("Signal handler ready");
	switch (errno = pthread_barrier_wait(&OSCAP_GSYM(th_barrier)))
	{
	case 0:
	case PTHREAD_BARRIER_SERIAL_THREAD:
		break;
	default:
		dE("pthread_barrier_wait: %d, %s.", errno, strerror(errno));
		return (NULL);
	}

	while (sigwaitinfo(&siset, &siinf) != -1) {

		dD("Received signal %d from %u (%s)",
		   siinf.si_signo, (unsigned int)siinf.si_pid,
		   getppid() == siinf.si_pid ? "parent" : "not my parent");

#if defined(PROBE_SIGNAL_PARENTONLY)
		/* Listen only to signals sent from the parent process */
		if (getppid() != siinf.si_pid)
			continue;
#endif

		switch(siinf.si_signo) {
		case SIGUSR1:/* probe abort */
                        probe->probe_exitcode = ECONNABORTED;
			/* FALLTHROUGH */
                case SIGINT:
                case SIGTERM:
                case SIGQUIT:
                case SIGPIPE:
		{
			__thr_collection coll;

			coll.thr = NULL;
			coll.cnt = 0;

                        pthread_cancel(probe->th_input);

			/* collect IDs and cancel threads */
			rbt_walk_inorder2(probe->workers, __abort_cb, &coll, 0);

			/*
			 * Wait till all threads are canceled (they may temporarily disable
			 * cancelability), but at most 60 seconds per thread.
			 */
			for (; coll.cnt > 0; --coll.cnt) {
				probe_worker_t *thr = coll.thr[coll.cnt - 1];
#if defined(HAVE_PTHREAD_TIMEDJOIN_NP) && defined(HAVE_CLOCK_GETTIME)
				struct timespec j_tm;

				if (clock_gettime(CLOCK_REALTIME, &j_tm) == -1) {
					dE("clock_gettime(CLOCK_REALTIME): %d, %s.", errno, strerror(errno));
					continue;
				}

				j_tm.tv_sec += 60;

				if ((errno = pthread_timedjoin_np(thr->tid, NULL, &j_tm)) != 0) {
					dE("[%llu] pthread_timedjoin_np: %d, %s.", (uint64_t)thr->sid, errno, strerror(errno));
					/*
					 * Memory will be leaked here by continuing to the next thread. However, we are in the
					 * process of shutting down the whole probe. We're just nice and gave the probe_main()
					 * thread a chance to finish it's critical section which shouldn't take that long...
					 */
					continue;
				}
#else
				if ((errno = pthread_join(thr->tid, NULL)) != 0) {
					dE("pthread_join: %d, %s.", errno, strerror(errno));
					continue;
				}
#endif
				SEAP_msg_free(coll.thr[coll.cnt - 1]->msg);
                                oscap_free(coll.thr[coll.cnt - 1]);
			}

			oscap_free(coll.thr);
			goto exitloop;
		}
                case SIGUSR2:
                case SIGHUP:
                        /* ignore */
                        break;
                }
	}
exitloop:
	return (NULL);
}
static int read_environment(SEXP_t *pid_ent, SEXP_t *name_ent, probe_ctx *ctx)
{
	int err = 1, pid, fd;
	bool empty;
	size_t env_name_size;
	SEXP_t *env_name, *env_value, *item, *pid_sexp;
	DIR *d;
	struct dirent *d_entry;
	char *buffer, env_file[256], *null_char;
	ssize_t buffer_used;
	size_t buffer_size;

	d = opendir("/proc");
	if (d == NULL) {
		dE("Can't read /proc: errno=%d, %s.\n", errno, strerror (errno));
		return PROBE_EACCESS;
	}

	if ((buffer = oscap_realloc(NULL, BUFFER_SIZE)) == NULL) {
		dE("Can't allocate memory");
		closedir(d);
		return PROBE_EFAULT;
	}
	buffer_size = BUFFER_SIZE;

	while ((d_entry = readdir(d))) {
		if (strspn(d_entry->d_name, "0123456789") != strlen(d_entry->d_name))
			continue;

		pid = atoi(d_entry->d_name);
		pid_sexp = SEXP_number_newi_32(pid);

		if (probe_entobj_cmp(pid_ent, pid_sexp) != OVAL_RESULT_TRUE) {
			SEXP_free(pid_sexp);
			continue;
		}
		SEXP_free(pid_sexp);

		sprintf(env_file, "/proc/%d/environ", pid);

		if ((fd = open(env_file, O_RDONLY)) == -1) {
			dE("Can't open \"%s\": errno=%d, %s.\n", env_file, errno, strerror (errno));
			item = probe_item_create(
					OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL,
					"pid", OVAL_DATATYPE_INTEGER, (int64_t)pid,
					NULL
			);

			probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);
			probe_item_add_msg(item, OVAL_MESSAGE_LEVEL_ERROR,
					   "Can't open \"%s\": errno=%d, %s.", env_file, errno, strerror (errno));
			probe_item_collect(ctx, item);
			continue;
		}

		empty = true;

		if ((buffer_used = read(fd, buffer, buffer_size - 1)) > 0) {
			empty = false;
		}

		while (! empty) {
			while (! (null_char = memchr(buffer, 0, buffer_used))) {
				ssize_t s;
				if ((size_t)buffer_used >= buffer_size) {
					buffer_size += BUFFER_SIZE;
					buffer = oscap_realloc(buffer, buffer_size);
					if (buffer == NULL) {
						dE("Can't allocate memory");
						exit(ENOMEM);
					}

				}
				s = read(fd, buffer + buffer_used, buffer_size - buffer_used);
				if (s <= 0) {
					empty = true;
					buffer[buffer_used++] = 0;
				}
				else {
					buffer_used += s;
				}
			}

			do {
				char *eq_char = strchr(buffer, '=');
				if (eq_char == NULL) {
					/* strange but possible:
					 * $ strings /proc/1218/environ
 					/dev/input/event0 /dev/input/event1 /dev/input/event4 /dev/input/event3
					*/
					buffer_used -= null_char + 1 - buffer;
					memmove(buffer, null_char + 1, buffer_used);
					continue;
				}

				env_name_size =  eq_char - buffer;
				env_name = SEXP_string_new(buffer, env_name_size);
				env_value = SEXP_string_newf("%s", buffer + env_name_size + 1);
				if (probe_entobj_cmp(name_ent, env_name) == OVAL_RESULT_TRUE) {
					item = probe_item_create(
						OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL,
						"pid", OVAL_DATATYPE_INTEGER, (int64_t)pid,
						"name",  OVAL_DATATYPE_SEXP, env_name,
						"value", OVAL_DATATYPE_SEXP, env_value,
					      NULL);
					probe_item_collect(ctx, item);
					err = 0;
				}
				SEXP_free(env_name);
				SEXP_free(env_value);

				buffer_used -= null_char + 1 - buffer;
				memmove(buffer, null_char + 1, buffer_used);
			} while ((null_char = memchr(buffer, 0, buffer_used)));
		}

		close(fd);
	}
	closedir(d);
	oscap_free(buffer);
	if (err) {
		SEXP_t *msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR,
				"Can't find process with requested PID.");
		probe_cobj_add_msg(probe_ctx_getresult(ctx), msg);
		SEXP_free(msg);
		err = 0;
	}

	return err;
}
Exemple #26
0
static void *probe_icache_worker(void *arg)
{
        probe_icache_t *cache = (probe_icache_t *)(arg);
        probe_iqpair_t *pair, pair_mem;
        SEXP_ID_t       item_ID;

        assume_d(cache != NULL, NULL);

	pthread_setname_np(pthread_self(), "icache_worker");

        if (pthread_mutex_lock(&cache->queue_mutex) != 0) {
                dE("An error ocured while locking the queue mutex: %u, %s",
                   errno, strerror(errno));
                return (NULL);
        }

	pair = &pair_mem;
        dD("icache worker ready");

        switch (errno = pthread_barrier_wait(&OSCAP_GSYM(th_barrier)))
        {
        case 0:
        case PTHREAD_BARRIER_SERIAL_THREAD:
	        break;
        default:
	        dE("pthread_barrier_wait: %d, %s.",
	           errno, strerror(errno));
	        pthread_mutex_unlock(&cache->queue_mutex);
	        return (NULL);
        }

        while(pthread_cond_wait(&cache->queue_notempty, &cache->queue_mutex) == 0) {
                assume_d(cache->queue_cnt > 0, NULL);
        next:
                dD("Extracting item from the cache queue: cnt=%"PRIu16", beg=%"PRIu16"", cache->queue_cnt, cache->queue_beg);
                /*
                 * Extract an item from the queue and update queue beg, end & cnt
                 */
                pair_mem = cache->queue[cache->queue_beg];
#ifndef NDEBUG
		memset(cache->queue + cache->queue_beg, 0, sizeof(probe_iqpair_t));
#endif
                --cache->queue_cnt;
		++cache->queue_beg;

		if (cache->queue_beg == cache->queue_max)
			cache->queue_beg = 0;

		assume_d(cache->queue_cnt == 0 ?
			 cache->queue_end == cache->queue_beg :
			 cache->queue_end != cache->queue_beg, NULL);

                /*
                 * Release the mutex
                 */
                if (pthread_mutex_unlock(&cache->queue_mutex) != 0) {
                        dE("An error ocured while unlocking the queue mutex: %u, %s",
                           errno, strerror(errno));
                        abort();
                }

                dD("Signaling `notfull'");

                if (pthread_cond_signal(&cache->queue_notfull) != 0) {
                        dE("An error ocured while signaling the `notfull' condition: %u, %s",
                           errno, strerror(errno));
                        abort();
                }

                if (pair->cobj == NULL) {
                        /*
                         * Handle NOP case (synchronization)
                         */
                        assume_d(pair->p.cond != NULL, NULL);

                        dD("Handling NOP");

                        if (pthread_cond_signal(pair->p.cond) != 0) {
                                dE("An error ocured while signaling NOP condition: %u, %s",
                                   errno, strerror(errno));
                                abort();
                        }
                } else {
                        probe_citem_t *cached = NULL;

                        dD("Handling cache request");

                        /*
                         * Compute item ID
                         */
                        item_ID = SEXP_ID_v(pair->p.item);
                        dD("item ID=%"PRIu64"", item_ID);

                        /*
                         * Perform cache lookup
                         */
                        if (rbt_i64_get(cache->tree, (int64_t)item_ID, (void *)&cached) == 0) {
                                register uint16_t i;
				SEXP_t   rest1, rest2;
                                /*
                                 * Maybe a cache HIT
                                 */
                                dD("cache HIT #1");

                                for (i = 0; i < cached->count; ++i) {
                                        if (SEXP_deepcmp(SEXP_list_rest_r(&rest1, pair->p.item),
							 SEXP_list_rest_r(&rest2, cached->item[i])))
					{
						SEXP_free_r(&rest1);
						SEXP_free_r(&rest2);
                                                break;
					}

					SEXP_free_r(&rest1);
					SEXP_free_r(&rest2);
                                }

                                if (i == cached->count) {
                                        /*
                                         * Cache MISS
                                         */
                                        dD("cache MISS");

                                        cached->item = oscap_realloc(cached->item, sizeof(SEXP_t *) * ++cached->count);
                                        cached->item[cached->count - 1] = pair->p.item;

                                        /* Assign an unique item ID */
                                        probe_icache_item_setID(pair->p.item, item_ID);
                                } else {
                                        /*
                                         * Cache HIT
                                         */
                                        dD("cache HIT #2 -> real HIT");
                                        SEXP_free(pair->p.item);
                                        pair->p.item = cached->item[i];
                                }
                        } else {
                                /*
                                 * Cache MISS
                                 */
                                dD("cache MISS");
                                cached = oscap_talloc(probe_citem_t);
                                cached->item = oscap_talloc(SEXP_t *);
                                cached->item[0] = pair->p.item;
                                cached->count = 1;

                                /* Assign an unique item ID */
                                probe_icache_item_setID(pair->p.item, item_ID);

                                if (rbt_i64_add(cache->tree, (int64_t)item_ID, (void *)cached, NULL) != 0) {
                                        dE("Can't add item (k=%"PRIi64" to the cache (%p)", (int64_t)item_ID, cache->tree);

                                        oscap_free(cached->item);
                                        oscap_free(cached);

                                        /* now what? */
                                        abort();
                                }
                        }

                        if (probe_cobj_add_item(pair->cobj, pair->p.item) != 0) {
                            dW("An error ocured while adding the item to the collected object");
                        }
                }

                if (pthread_mutex_lock(&cache->queue_mutex) != 0) {
                        dE("An error ocured while re-locking the queue mutex: %u, %s",
                           errno, strerror(errno));
                        abort();
                }

                if (cache->queue_cnt > 0)
                        goto next;
        }

        return (NULL);
}
Exemple #27
0
static inline oval_result_t _evaluate_sysent_with_variable(struct oval_syschar_model *syschar_model, struct oval_entity *state_entity, struct oval_sysent *item_entity, oval_operation_t state_entity_operation, struct oval_state_content *content)
{
	oval_syschar_collection_flag_t flag;
	oval_result_t ent_val_res;

	struct oval_variable *state_entity_var;
	if ((state_entity_var = oval_entity_get_variable(state_entity)) == NULL) {
		oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL variable");
		return -1;
	}

	if (0 != oval_syschar_model_compute_variable(syschar_model, state_entity_var)) {
		return -1;
	}

	flag = oval_variable_get_collection_flag(state_entity_var);
	switch (flag) {
	case SYSCHAR_FLAG_COMPLETE:
	case SYSCHAR_FLAG_INCOMPLETE:{
		struct oresults var_ores;
		struct oval_value_iterator *val_itr;

		ores_clear(&var_ores);

		val_itr = oval_variable_get_values(state_entity_var);
		while (oval_value_iterator_has_more(val_itr)) {
			struct oval_value *var_val;
			char *state_entity_val_text = NULL;
			oval_result_t var_val_res;

			var_val = oval_value_iterator_next(val_itr);
			state_entity_val_text = oval_value_get_text(var_val);
			if (state_entity_val_text == NULL) {
				dE("Found NULL variable value text.");
				ores_add_res(&var_ores, OVAL_RESULT_ERROR);
				break;
			}
			oval_datatype_t state_entity_val_datatype = oval_value_get_datatype(var_val);

			var_val_res = oval_ent_cmp_str(state_entity_val_text, state_entity_val_datatype, item_entity, state_entity_operation);
			if (var_val_res == OVAL_RESULT_ERROR) {
				dE("Error occured when comparing a variable '%s' value '%s' with collected item entity = '%s'",
					oval_variable_get_id(state_entity_var), state_entity_val_text, oval_sysent_get_value(item_entity));
			}
			ores_add_res(&var_ores, var_val_res);
		}
		oval_value_iterator_free(val_itr);

		oval_check_t var_check = oval_state_content_get_var_check(content);
		ent_val_res = ores_get_result_bychk(&var_ores, var_check);
		} break;
	case SYSCHAR_FLAG_ERROR:
	case SYSCHAR_FLAG_DOES_NOT_EXIST:
	case SYSCHAR_FLAG_NOT_COLLECTED:
	case SYSCHAR_FLAG_NOT_APPLICABLE:
		ent_val_res = OVAL_RESULT_ERROR;
		break;
	default:
		ent_val_res = -1;
	}

	return ent_val_res;
}
Exemple #28
0
static int rpmverify_collect(probe_ctx *ctx,
                             const char *name, oval_operation_t name_op,
                             const char *file, oval_operation_t file_op,
			     SEXP_t *name_ent, SEXP_t *filepath_ent,
                             uint64_t flags,
                             void (*callback)(probe_ctx *, struct rpmverify_res *))
{
	rpmdbMatchIterator match;
        rpmVerifyAttrs omit = (rpmVerifyAttrs)(flags & RPMVERIFY_RPMATTRMASK);
	Header pkgh;
        pcre *re = NULL;
	int  ret = -1;

        /* pre-compile regex if needed */
        if (file_op == OVAL_OPERATION_PATTERN_MATCH) {
                const char *errmsg;
                int erroff;

                re = pcre_compile(file, PCRE_UTF8, &errmsg,  &erroff, NULL);

                if (re == NULL) {
                        /* TODO */
                        return (-1);
                }
        }

        RPMVERIFY_LOCK;

        switch (name_op) {
        case OVAL_OPERATION_EQUALS:
                match = rpmtsInitIterator (g_rpm.rpmts, RPMTAG_NAME, (const void *)name, 0);

                if (match == NULL) {
                        ret = 0;
                        goto ret;
                }

                ret = rpmdbGetIteratorCount (match);

                break;
	case OVAL_OPERATION_NOT_EQUAL:
                match = rpmtsInitIterator (g_rpm.rpmts, RPMDBI_PACKAGES, NULL, 0);

                if (match == NULL) {
                        ret = 0;
                        goto ret;
                }

                if (rpmdbSetIteratorRE (match, RPMTAG_NAME, RPMMIRE_GLOB, "*") != 0)
                {
                        ret = -1;
                        goto ret;
                }

                break;
        case OVAL_OPERATION_PATTERN_MATCH:
                match = rpmtsInitIterator (g_rpm.rpmts, RPMDBI_PACKAGES, NULL, 0);

                if (match == NULL) {
                        ret = 0;
                        goto ret;
                }

                if (rpmdbSetIteratorRE (match, RPMTAG_NAME, RPMMIRE_REGEX,
                                        (const char *)name) != 0)
                {
                        ret = -1;
                        goto ret;
                }

                break;
        default:
                /* not supported */
                dE("package name: operation not supported");
                ret = -1;
                goto ret;
        }

	assume_d(RPMTAG_BASENAMES != 0, -1);
	assume_d(RPMTAG_DIRNAMES  != 0, -1);

        while ((pkgh = rpmdbNextIterator (match)) != NULL) {
                rpmfi  fi;
		rpmTag tag[2] = { RPMTAG_BASENAMES, RPMTAG_DIRNAMES };
                struct rpmverify_res res;
                errmsg_t rpmerr;
		int i;
		SEXP_t *name_sexp;

                res.name = headerFormat(pkgh, "%{NAME}", &rpmerr);

		name_sexp = SEXP_string_newf("%s", res.name);
		if (probe_entobj_cmp(name_ent, name_sexp) != OVAL_RESULT_TRUE) {
			SEXP_free(name_sexp);
			continue;
		}
		SEXP_free(name_sexp);

                /*
                 * Inspect package files & directories
                 */
		for (i = 0; i < 2; ++i) {
		  fi = rpmfiNew(g_rpm.rpmts, pkgh, tag[i], 1);

		  while (rpmfiNext(fi) != -1) {
		    SEXP_t *filepath_sexp;

		    res.fflags = rpmfiFFlags(fi);
		    res.oflags = omit;

		    if (((res.fflags & RPMFILE_CONFIG) && (flags & RPMVERIFY_SKIP_CONFIG)) ||
			((res.fflags & RPMFILE_GHOST)  && (flags & RPMVERIFY_SKIP_GHOST)))
		      continue;

		    res.file   = strdup(rpmfiFN(fi));

		    filepath_sexp = SEXP_string_newf("%s", res.file);
		    if (probe_entobj_cmp(filepath_ent, filepath_sexp) != OVAL_RESULT_TRUE) {
		      SEXP_free(filepath_sexp);
		      free(res.file);
		      continue;
		    }
		    SEXP_free(filepath_sexp);

		    if (rpmVerifyFile(g_rpm.rpmts, fi, &res.vflags, omit) != 0)
		      res.vflags = RPMVERIFY_FAILURES;

		    callback(ctx, &res);
		    free(res.file);
		  }

		  rpmfiFree(fi);
		}
	}

	match = rpmdbFreeIterator (match);
        ret   = 0;
ret:
        if (re != NULL)
                pcre_free(re);

        RPMVERIFY_UNLOCK;
        return (ret);
}
extern "C" magma_int_t
magma_zbulge_applyQ_v2_m(
    magma_int_t ngpu,
    magma_side_t side,
    magma_int_t NE, magma_int_t N,
    magma_int_t NB, magma_int_t Vblksiz,
    magmaDoubleComplex *E, magma_int_t lde,
    magmaDoubleComplex *V, magma_int_t ldv,
    magmaDoubleComplex *T, magma_int_t ldt,
    magma_int_t *info)
{
    //%===========================
    //%   local variables
    //%===========================
    magma_int_t Vm, Vn, mt, nt;
    magma_int_t myrow, mycol, blkj, blki;
    magma_int_t blkid,vpos,tpos;
    magma_int_t firstrow, nbcolinvolvd;
    magma_int_t versionL  = 113;
    magma_int_t versionR  = 92;
    magma_int_t Vchunksiz = 10;
    *info=0;

    /* Quick return */
    if ( NE == 0 ) {
        return *info;
    }
    if ( N == 0 ) {
        return *info;
    }
    if ( NB == 0 ) {
        return *info;
    }
    /* ==========================================
     * some infos for developer
     * Initialisation and checking nb of cores
     * ==========================================*/
    /* we have 2 algo for left (113 114) and 2 algo for right (91 92)
     * which correspond to versionL versionR.
     * They are very similar (detail explained in tech report and matlab code)
     * however version 114 and 92 improve locality.
     * while version 113 is used in case WNATZ=1 (construct Q2) which allow
     * the construction to be done in an optimized way taking into
     * consideration that the matrix is Identity so making less flops.
     *
    */

    // Initialize streaming and events
    magma_device_sync();
    magma_device_t orig_dev;
    magma_getdevice( &orig_dev );
    magma_queue_t orig_stream;
    magmablasGetKernelStream( &orig_stream );

    magma_int_t  nbevents =2, nstream=2;
    magma_queue_t streams[MagmaMaxGPUs][20];
    magma_event_t  myevent[MagmaMaxGPUs][20];
    for( magma_int_t dev = 0; dev < ngpu; ++dev ) {
        magma_setdevice( dev );
        for( magma_int_t i = 0; i < nstream; ++i ) {
            magma_queue_create( &streams[dev][i] );
        }
        for( magma_int_t i = 0; i < nbevents; ++i ) {
            cudaEventCreateWithFlags(&myevent[dev][i],cudaEventDisableTiming);
        }
    }



    // Azzam 21/11/2012
    // NOTE THAT dwork was of size 2*NE*Vblksiz+...
    // but I am thinking why not modifing it to NE*Vblksiz+...
    // BUT NO because the 2* is used because of making 2 streams working and so
    // they might be using dwork in parallel
    magmaDoubleComplex *dE[MagmaMaxGPUs];
    magmaDoubleComplex *dwork[MagmaMaxGPUs], *dwork0[MagmaMaxGPUs], *dwork1[MagmaMaxGPUs];
    //magmaDoubleComplex *dwvt[MagmaMaxGPUs];
    magmaDoubleComplex *dwvt0[MagmaMaxGPUs], *dwvt1[MagmaMaxGPUs];
    magmaDoubleComplex *dT0[MagmaMaxGPUs], *dV0[MagmaMaxGPUs], *dT1[MagmaMaxGPUs], *dV1[MagmaMaxGPUs];
    magma_int_t dev;
    magma_int_t ldde = N;
    magma_int_t lddv = ldv;
    magma_int_t lddt = ldt;
    magma_int_t ne_loc = magma_ceildiv(NE, ngpu);
    if (ne_loc < 256)
       ne_loc=256;
    magma_int_t dwVTsiz  = lddv*Vblksiz;  // lddv*lddv + lddv*NE; // lddv*Vblksiz;
    magma_int_t dworksiz = ne_loc*Vblksiz;  // lddv*Vblksiz;      // NE*Vblksiz;

    ngpu = min(ngpu, magma_ceildiv(NE,ne_loc)); // Don't use GPU that will not have data.
    // copy dE to GPUs
    for (dev=0; dev < ngpu; ++dev) {
        magma_setdevice( dev );
        if (MAGMA_SUCCESS != magma_zmalloc( &dE[dev], ldde * ne_loc)) {
            printf ("!!!!  magma_zbulge_applyQ magma_alloc failed for: dE\n" );
            exit(-1);
        }
        if (MAGMA_SUCCESS != magma_zmalloc( &dwork[dev], 2*dworksiz + 2*dwVTsiz + 2*Vchunksiz* (Vblksiz* (lddv+lddt)) )) {
            printf ("!!!!  magma_zbulge_applyQ magma_alloc failed for: dwork\n" );
            exit(-1);
        }

        dwork0[dev] = dwork[dev];               // size = dworksiz;
        dwork1[dev] = dwork0[dev] + dworksiz;   // size = dworksiz;
        dwvt0[dev]  = dwork[dev] + 2*dworksiz;  // size = dwVTsiz;
        dwvt1[dev]  = dwvt0[dev] + dwVTsiz;     // size = dwVTsiz;
        dV0[dev]    = dwork[dev] + 2*dworksiz + 2*dwVTsiz;
        dT0[dev]    = dV0[dev]   + Vchunksiz*Vblksiz*lddv;
        dV1[dev]    = dT0[dev]   + Vchunksiz*Vblksiz*lddt;
        dT1[dev]    = dV1[dev]   + Vchunksiz*Vblksiz*lddv;

        magma_int_t ie_loc = min(ne_loc, NE - ne_loc*dev);
        magma_zsetmatrix_async( N, ie_loc, E+lde*ne_loc*dev, lde, dE(dev, 0, 0), ldde, streams[dev][1] );
    }


    // make overlapped copy
    magma_int_t ncpy = 0;
    magma_int_t copyed=0, copyst=0;
    magma_int_t blkcnt,nothing, mysiz, flip, vld,tld, locpos;
    findVTsiz(N, NB, Vblksiz, &blkcnt, &nothing);
    
    flip = 0;


    /* SIDE LEFT  meaning apply E = Q*E = (q_1*q_2*.....*q_n) * E ==> so traverse Vs in reverse order (forward) from q_n to q_1
     *            Also E is splitten by row meaning each apply consist in a block of row (horizontal block) */
    /* SIDE RIGHT meaning apply E = E*Q = E * (q_1*q_2*.....*q_n) ==> so tarverse Vs in normal  order (forward) from q_1 to q_n
     *            Also E is splitten by col meaning each apply consist in a block of col (vertical block) */

    #ifdef ENABLE_DEBUG
    printf("  APPLY Q_v22_m GPU with NGPU %d  N %d, NE %d,  NB %d, Vblksiz %d, versionL %d versionR %d  SIDE %c \n",
          ngpu, N, NE, NB, Vblksiz, versionL, versionR, side);
    #endif


    /*
     * MagmamaLeft
     */
    if (side == MagmaLeft) {
        /*
         * Version 113:
         * loop over the block_col (nt) and for each find the
         * number of tiles (mt) in this block_col. then loop over mt, find
         * the size of the V's(Vm,Vn) and apply it to the corresponding
         * portion of E.
         */
        if ( versionL == 113 ) {
            nt  = magma_ceildiv((N-1),Vblksiz);
            for (blkj=nt-1; blkj >= 0; blkj--) {
                /* the index of the first row on the top of block (blkj) */
                firstrow = blkj * Vblksiz + 1;
                /*find the number of tile for this block */
                if ( blkj == nt-1 )
                    mt = magma_ceildiv( N -  firstrow,    NB);
                else
                    mt = magma_ceildiv( N - (firstrow+1), NB);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blki=mt; blki > 0; blki--) {
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow     = firstrow + (mt-blki)*NB;
                    mycol     = blkj*Vblksiz;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if ( ( blkj == nt-1 ) && ( blki == mt ) ) {
                        Vn = min (Vblksiz, Vm);
                    } else {
                        Vn = min (Vblksiz, Vm-1);
                    }
                    /*calculate the pointer to the Vs and the Ts.
                     * Note that Vs and Ts have special storage done
                     * by the bulgechasing function*/
                    //printf("voici blkj %d blki %d  Vm %d  Vn %d mycol %d vpos %d \n",blkj,blki,Vm, Vn,mycol,vpos);
                    magma_bulge_findpos113(N, NB, Vblksiz, mycol, myrow, &blkid);
               
                    // COPY Vchunksiz Vs and Vchunksiz Ts to GPU and store it in dV0/dV1 and dT0/dT1
                    if (ncpy == 0) {
                        // flip = 1 for this.
                        copyst = 0;                             // meaning that copy will start copying from blkid =copyst
                        copyed = min(copyst+Vchunksiz, blkcnt); // meaning that copy will end copying at blkid =copyed-1==> next copy had to start at copyed
                        mysiz  = copyed-copyst;                 // the size of the chunk to be copied
                        if (mysiz > 0) {
                            ncpy = 1;
                            flip = 1;
                            vpos = copyst*Vblksiz*ldv;
                            tpos = copyst*Vblksiz*ldt;
                            vld  = mysiz * ldv;
                            tld  = mysiz * ldt;
                            for( dev = 0; dev < ngpu; ++dev ) {
                                magma_setdevice( dev );
                                magmablasSetKernelStream( streams[ dev ][ 1 ] );
                                magma_zsetmatrix_async(vld, Vblksiz, V(vpos), vld, dV1[dev], vld, streams[dev][1]);
                                magma_zsetmatrix_async(tld, Vblksiz, T(tpos), tld, dT1[dev], tld, streams[dev][1]);
                            }
                            //printf("doing the first copy   of mysiz %2d copyst %2d copyed %2d vpos %8d tpos %8d into dV1 dT1\n",mysiz,copyst,copyed,vpos,tpos);
                        }
                    }
                   
                    if (blkid == copyst) {
                        flip   = ncpy % 2;
                        copyst = copyed;                             // meaning that copy will start copying from blkid =copyst
                        copyed = min(copyst+Vchunksiz, blkcnt); // meaning that copy will end copying at blkid =copyed-1==> next copy had to start at copyed
                        mysiz  = copyed-copyst;                 // the size of the chunk to be copied
                        //printf(" get to copy blkid %d blkid+(2*Vchunksiz) %d copyst %d copyed %d\n",blkid,blkid+(Vchunksiz),copyst,copyed);
                        if (mysiz > 0) {
                            ncpy = ncpy + 1;
                            vpos = copyst*Vblksiz*ldv;
                            tpos = copyst*Vblksiz*ldt;
                            vld  = mysiz * ldv;
                            tld  = mysiz * ldt;
                            if (flip == 0) { // now I am working on dV0 so copy the next and put it on dV1
                                //printf("doing overlapping copy of mysiz %2d copyst %2d copyed %2d vpos %8d tpos %8d into dV1 dT1\n",mysiz,copyst,copyed,vpos,tpos);
                                for( dev = 0; dev < ngpu; ++dev ) {
                                    magma_setdevice( dev );
                                    magmablasSetKernelStream( streams[ dev ][ 1 ] );
                                    magma_zsetmatrix_async(vld, Vblksiz, V(vpos), vld, dV1[dev], vld, streams[dev][1]);
                                    magma_zsetmatrix_async(tld, Vblksiz, T(tpos), tld, dT1[dev], tld, streams[dev][1]);
                                }
                            } else { // now I am working on dV1 so copy the next and put it on dV0
                                //printf("doing overlapping copy of mysiz %2d copyst %2d copyed %2d vpos %8d tpos %8d into dV0 dT0\n",mysiz,copyst,copyed,vpos,tpos);
                                for( dev = 0; dev < ngpu; ++dev ) {
                                    magma_setdevice( dev );
                                    magmablasSetKernelStream( streams[ dev ][ 0 ] );
                                    magma_zsetmatrix_async(vld, Vblksiz, V(vpos), vld, dV0[dev], vld, streams[dev][0]);
                                    magma_zsetmatrix_async(tld, Vblksiz, T(tpos), tld, dT0[dev], tld, streams[dev][0]);
                                }
                            }
                        }
                    }

                    if ((Vm > 0) && (Vn > 0)) {
                        locpos = blkid%Vchunksiz;
                        magma_int_t lcvpos   = locpos*Vblksiz*lddv;
                        magma_int_t lctpos   = locpos*Vblksiz*lddt;
                        //printf("voici blkj %d blki %d  Vm %d  Vn %d mycol %d locvpos %5d loctpos %5d  blkid %2d  using data in dV%1d dT%1d \n",blkj,blki,Vm, Vn,mycol,lcvpos,lctpos, blkid,flip,flip);
                        if (flip == 0) {
                            for( dev = 0; dev < ngpu; ++dev ) {
                                magma_int_t ie_loc   = min(ne_loc, NE - ne_loc*dev);
                                magma_int_t nr_bl = magma_ceildiv(ie_loc,10000);       //nr of blocks
                                magma_int_t sz_bl = magma_ceildiv(ie_loc,nr_bl*64)*64; //maximum size of blocks (to have blocks of around the same size and multiple of 64)
                                magma_int_t ib;                                        //size of current block
                                magma_setdevice( dev );
                                magmablasSetKernelStream(streams[dev][0]);
                                magma_queue_wait_event( streams[dev][0], myevent[dev][1] );
                                for (magma_int_t i=0; i < ie_loc; i += sz_bl) {
                                    ib = min(sz_bl, ie_loc-i);
                                    //magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV0[dev]+lcvpos, lddv, dT0[dev]+lctpos, lddt, dE(dev,myrow,i), ldde, dwork0[dev], ib);
                                    magma_zlarfb_gpu_gemm( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV0[dev]+lcvpos, lddv, dT0[dev]+lctpos, lddt, dE(dev,myrow,i), ldde, dwork0[dev], ib, dwvt0[dev], Vm);
                                }
                                magma_event_record( myevent[dev][0], streams[dev][0] );
                            }
                        } else {
                            for( dev = 0; dev < ngpu; ++dev ) {
                                magma_int_t ie_loc   = min(ne_loc, NE - ne_loc*dev);
                                magma_int_t nr_bl = magma_ceildiv(ie_loc,10000);       //nr of blocks
                                magma_int_t sz_bl = magma_ceildiv(ie_loc,nr_bl*64)*64; //maximum size of blocks (to have blocks of around the same size and multiple of 64)
                                magma_int_t ib;                                        //size of current block
                                magma_setdevice( dev );
                                magmablasSetKernelStream(streams[dev][1]);
                                magma_queue_wait_event( streams[dev][1], myevent[dev][0] );
                                for (magma_int_t i=0; i < ie_loc; i += sz_bl) {
                                    ib = min(sz_bl, ie_loc-i);
                                    //magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV1[dev]+lcvpos, lddv, dT1[dev]+lctpos, lddt, dE(dev,myrow,i), ldde, dwork1[dev], ib);
                                    magma_zlarfb_gpu_gemm( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV1[dev]+lcvpos, lddv, dT1[dev]+lctpos, lddt, dE(dev,myrow,i), ldde, dwork1[dev], ib, dwvt1[dev], Vm);
                                }
                                magma_event_record( myevent[dev][1], streams[dev][1] );
                            }
                        }
                    }  // end for (Vm &Vn) > 0
                } // end for blki
            } // end for blkj
        } // end if version=113
        /*
         * Version 114:
         * loop over the block_row (mt) and for each find diagonally the
         * number of tiles (nt) in this block_row. then loop over nt, find
         * the size of the V's(Vm,Vn) and apply it to the corresponding
         * portion of E.
         */
        else {
            printf("versionL 114 not implemented in zbulge_applyQ_v2_m\n");
            exit(-1);
            mt    = magma_ceildiv((N-1),NB);
            for (blki = mt; blki > 0; blki--) {
                /* nbcolinvolvd = number of column corresponding to this block_row (blki) */
                nbcolinvolvd = min(N-1, blki*NB);
                /*find the number of tile for this block (diagonal row of tiles) */
                nt = magma_ceildiv(nbcolinvolvd,Vblksiz);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blkj = nt-1; blkj >= 0; blkj--) {
                    /* the index of the first row of the first col meaning
                     * the block on the top left (blki) */
                    firstrow = (mt-blki)*NB+1;
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow    = firstrow + blkj*Vblksiz;
                    mycol    = blkj*Vblksiz;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if ( ( blkj == nt-1 ) && ( blki == mt ) ) {
                        Vn = min (Vblksiz, Vm);
                    } else {
                        Vn = min (Vblksiz, Vm-1);
                    }

                    if ((Vm > 0) && (Vn > 0)) {
                        /*calculate the pointer to the Vs and the Ts.
                         * Note that Vs and Ts have special storage done
                         * by the bulgechasing function*/
                        /*
                        magma_bulge_findVTpos(N, NB, Vblksiz, mycol, myrow, ldv, ldt, &vpos, &tpos);
                        magma_zsetmatrix_async(Vm, Vn, V(vpos), ldv, dV0, lddv, NULL);
                        magma_zsetmatrix_async(Vn,  Vn, T(tpos), ldt, dT0, lddt, NULL);
                        //printf("voici blki %d  rownbm %d mycol %d  coled %d  blkid %d vpos %d  tpos %d\n", blki, rownbm, mycol, coled, blkid, vpos, tpos);
                        for (magma_int_t i=0; i < NE; i += sz_bl) {
                            ib = min(sz_bl, NE-i);
                            magma_zlarfb_gpu( MagmaLeft, MagmaNoTrans, MagmaForward, MagmaColumnwise, Vm, ib, Vn, dV0, lddv, dT0, lddt, dE(myrow,i), ldde, dwork, NE);
                        }
                        */
                    } // end for (Vm &Vn) > 0
                } // end for blkj
            } // end for blki
        } // end version 114
    } // end LEFT
    /*
     * MagmaRight
     */
    else {
        printf("Side 'R' not implemented in zbulge_applyQ_v2_m\n");
        exit(-1);
        /*
         * Version 91:
         */
        if ( versionR == 91 ) {
            nt  = magma_ceildiv((N-1),Vblksiz);
            for (blkj=0; blkj < nt; blkj++) {
                /* the index of the first myrow on the top of block (blkj) */
                firstrow = blkj * Vblksiz + 1;
                /*find the number of tile for this block */
                if ( blkj == nt-1 )
                    mt = magma_ceildiv( N -  firstrow,    NB);
                else
                    mt = magma_ceildiv( N - (firstrow+1), NB);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blki=1; blki <= mt; blki++) {
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow  = firstrow + (mt-blki)*NB;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if ( (blkj == nt-1) && (blki == mt) ) {
                        Vn = min (Vblksiz, Vm);
                    } else {
                        Vn = min (Vblksiz, Vm-1);
                    }
                    mycol     = blkj*Vblksiz;
                    if ((Vm > 0) && (Vn > 0)) {
                        /*calculate the pointer to the Vs and the Ts.
                         * Note that Vs and Ts have special storage done
                         * by the bulgechasing function*/
                        /*
                        magma_bulge_findVTpos(N, NB, Vblksiz, mycol, myrow, ldv, ldt, &vpos, &tpos);
                        magma_zsetmatrix_async(Vm, Vn, V(vpos), ldv, dV0, lddv, NULL);
                        magma_zsetmatrix_async(Vn,  Vn, T(tpos), ldt, dT0, lddt, NULL);
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, NE, Vm, Vn, dV0, lddv, dT0, lddt, dE(0, myrow), ldde, dwork, NE);
                        */
                    } // end for (Vm &Vn) > 0
                } // end for blki
            } // end fo blkj
        } // end of version 91
        /*
         * Version 92:
         */
        else {
            mt    = magma_ceildiv((N-1),NB);
            for (blki = 1; blki <= mt; blki++) {
                /* nbcolinvolvd = number of column corresponding to this block_row (blki) */
                nbcolinvolvd = min(N-1, blki*NB);
                /*find the number of tile for this block (diagonal row of tiles) */
                nt = magma_ceildiv(nbcolinvolvd,Vblksiz);
                /*loop over the tiles find the size of the Vs and apply it */
                for (blkj = 0; blkj < nt; blkj++) {
                    /* the index of the first row of the first col meaning
                     * the block on the top left (blki) */
                    firstrow = (mt-blki)*NB+1;
                    /*calculate the size of each losange of Vs= (Vm,Vn)*/
                    myrow    = firstrow + blkj*Vblksiz;
                    mycol    = blkj*Vblksiz;
                    Vm = min( NB+Vblksiz-1, N-myrow);
                    if ( ( blkj == nt-1 ) && ( blki == mt ) ) {
                        Vn = min (Vblksiz, Vm);
                    } else {
                        Vn = min (Vblksiz, Vm-1);
                    }
                    if ((Vm > 0) && (Vn > 0)) {
                        /*calculate the pointer to the Vs and the Ts.
                         * Note that Vs and Ts have special storage done
                         * by the bulgechasing function*/
                        /*
                        magma_bulge_findVTpos(N, NB, Vblksiz, mycol, myrow, ldv, ldt, &vpos, &tpos);
                        magma_zsetmatrix_async(Vm, Vn, V(vpos), ldv, dV0, lddv, NULL);
                        magma_zsetmatrix_async(Vn,  Vn, T(tpos), ldt, dT0, lddt, NULL);
                        magma_zlarfb_gpu( MagmaRight, MagmaNoTrans, MagmaForward, MagmaColumnwise, NE, Vm, Vn, dV0, lddv, dT0, lddt, dE(0, myrow), ldde, dwork, NE);
                        */
                    } // end for (Vm &Vn) > 0
                } //end for blkj
            } // end for blki
        } //end of version 92
    } // end RIGHT

    // copy back the dE form each GPU
    for( dev = 0; dev < ngpu; ++dev ) {
        magma_setdevice( dev );
        magmablasSetKernelStream(streams[dev][0]);
        magma_queue_wait_event( streams[dev][0], myevent[dev][1] );
        magma_queue_wait_event( streams[dev][0], myevent[dev][0] );
        magma_int_t ie_loc   = min(ne_loc, NE - ne_loc*dev);
        magma_zgetmatrix_async( N, ie_loc, dE(dev, 0, 0), ldde, E+lde*ne_loc*dev, lde, streams[dev][0] );
        magma_event_record( myevent[dev][0], streams[dev][0] );
    }


    for( magma_int_t dev = 0; dev < ngpu; ++dev ) {
        magma_setdevice( dev );
        magmablasSetKernelStream(streams[dev][0]);
        magma_queue_wait_event( streams[dev][0], myevent[dev][0] );
        magma_device_sync(); // no need for synchronize
        magma_free(dwork[dev]);
        magma_free(dE[dev]);
        for( magma_int_t i = 0; i < nbevents; ++i ) {
            magma_event_destroy( myevent[dev][i] );
        }
        for( magma_int_t i = 0; i < nstream; ++i ) {
            magma_queue_destroy( streams[dev][i] );
        }
    }

    magma_setdevice( orig_dev );
    magmablasSetKernelStream( orig_stream );
    return *info;
}
Exemple #30
0
int probe_main(probe_ctx *ctx, void *mutex)
{
        LDAP        *ldp;
        LDAPMessage *ldpres, *entry;

        SEXP_t *se_ldap_behaviors = NULL, *se_relative_dn = NULL;
        SEXP_t *se_suffix = NULL, *se_attribute = NULL;
        SEXP_t *sa_scope, *sv_op;
        SEXP_t *item;
        SEXP_t *probe_in;

        char *relative_dn = NULL;
        char *suffix = NULL, *xattribute = NULL;
        char *uri_list, *uri, *uri_save, *attr;

        int   scope;
        char  base[2048];
        char *attrs[3];

        bool a_pattern_match = false, rdn_pattern_match = false;

        /* runtime */
#if defined(PROBE_LDAP_MUTEX)
        assume_r(mutex != NULL, PROBE_EINIT);
#endif
        probe_in = probe_ctx_getobject(ctx);
        se_ldap_behaviors = probe_obj_getent(probe_in, "behaviors", 1);

        if (se_ldap_behaviors != NULL) {
                sa_scope = probe_ent_getattrval(se_ldap_behaviors, "scope");
                SEXP_free(se_ldap_behaviors);

                if (sa_scope == NULL) {
                        dE("Atrribute `scope' is missing!");
                        return (PROBE_ENOATTR);
                }

                if (!SEXP_stringp(sa_scope)) {
                        dE("Invalid value type of the `scope' attribute.");
                        SEXP_free(sa_scope);
                        return (PROBE_EINVAL);
                }

                if (SEXP_strcmp(sa_scope, "ONE") == 0)
                        scope = LDAP_SCOPE_ONELEVEL;
                else if (SEXP_strcmp(sa_scope, "BASE") == 0)
                        scope = LDAP_SCOPE_BASE;
                else if (SEXP_strcmp(sa_scope, "SUBTREE") == 0)
                        scope = LDAP_SCOPE_SUBTREE;
                else {
                        dE("Invalid value of the `scope' attribute.");
                        SEXP_free(sa_scope);
                        return (PROBE_EINVAL);
                }

                SEXP_free(sa_scope);
        } else
                scope = LDAP_SCOPE_BASE;

#define get_string(dst, se_dst, obj, ent_name)                          \
	do {								\
		SEXP_t *__sval;						\
									\
		__sval = probe_obj_getentval (obj, ent_name, 1);	\
									\
		if (__sval != NULL) {					\
                        (dst) = SEXP_string_cstr (__sval);              \
									\
                        if ((dst) == NULL) {                            \
                                SEXP_free(__sval);                      \
                                return (PROBE_EINVAL);                  \
                        }                                               \
                                                                        \
                        (se_dst) = __sval;                              \
		} else {						\
			return (PROBE_ENOATTR);				\
		}							\
	} while (0)

        get_string(suffix,      se_suffix,      probe_in, "suffix");
        get_string(relative_dn, se_relative_dn, probe_in, "relative_dn");
        get_string(xattribute,  se_attribute,   probe_in, "attribute");

        if ((sv_op = probe_ent_getattrval(se_relative_dn, "operation")) != NULL) {
                if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH)
                        rdn_pattern_match = true;
                SEXP_free(sv_op);
        }

        if ((sv_op = probe_ent_getattrval(se_attribute, "operation")) != NULL) {
                if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH)
                        a_pattern_match = true;
                SEXP_free(sv_op);
        }

        /*
         * Construct the attribute array for ldap_search_*
         *
         * nil   -> "1.1"
         * .*    -> "*"
         * "foo" -> "foo"
         */
        attrs[0] = "objectClass";

        if (xattribute == NULL)
                attrs[1] = strdup("1.1"); /* no attibutes */
        else if (a_pattern_match)
                attrs[1] = strdup("*");   /* collect all, we'll filter them afterwards */
        else
                attrs[1] = xattribute;     /* no pattern match, use the string directly */

        attrs[2] = NULL;

        /*
         * Construct `base'
         */
        assume_r(((relative_dn ? strlen(relative_dn) : 0) +
                  (     suffix ? strlen(suffix)      : 0) + 2) < (sizeof base/sizeof(char)),
                 PROBE_ERANGE);

        if (relative_dn != NULL) {
                strcpy(base, relative_dn);
                strcat(base, ",");
                strcat(base, suffix);
        } else
                strcpy(base, suffix);

        /*
         * Get URIs
         */
        if (ldap_get_option(NULL, LDAP_OPT_URI, &uri_list) != LDAP_OPT_SUCCESS) {
                item = probe_item_creat("ldap57_item", NULL, NULL);

                probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);
                probe_item_collect(ctx, item);

                dE("ldap_get_option failed");
                goto fail0;
        }

        /*
         * Query each URI
         */
        for (;;) {
                char *entry_dn = NULL;

                if ((uri = strtok_r(uri_list, " ,", &uri_save)) == NULL)
                        break;

                ldp = NULL;

                if (ldap_initialize(&ldp, uri) != LDAP_SUCCESS)
                        continue;

                if (ldap_search_ext_s(ldp, base, scope, NULL, attrs, 0,
                                      NULL /* serverctrls */,
                                      NULL /* clientctrls */,
                                      NULL /* timeout */,
                                      0, &ldpres) != LDAP_SUCCESS)
                {
                        item = probe_item_creat("ldap57_item", NULL, NULL);

                        probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);
                        probe_item_collect(ctx, item);

                        dE("ldap_search_ext_s failed");
                        goto fail0;
                }

                entry    = ldap_first_entry(ldp, ldpres);
                entry_dn = ldap_get_dn(ldp, entry);

                while (entry != NULL) {
                        BerElement *berelm = NULL;

                        attr = ldap_first_attribute(ldp, entry, &berelm);

                        /* XXX: pattern match filter */

                        while (attr != NULL) {
                                SEXP_t   *se_value = NULL;
                                ber_tag_t bertag   = LBER_DEFAULT;
                                ber_len_t berlen   = 0;
                                Sockbuf  *berbuf   = NULL;
                                SEXP_t    se_tmp_mem;

                                berbuf = ber_sockbuf_alloc();

                                /*
                                 * Prepare the value (record) entity. Collect only
                                 * primitive (i.e. simple) types.
                                 */
                                se_value = probe_ent_creat1("value", NULL, NULL);
                                probe_ent_setdatatype(se_value, OVAL_DATATYPE_RECORD);

                                /*
                                 * XXX: does ber_get_next() return LBER_ERROR after the last value?
                                 */
                                while ((bertag = ber_get_next(berbuf, &berlen, berelm)) != LBER_ERROR) {
                                        SEXP_t *field = NULL;
                                        oval_datatype_t field_type = OVAL_DATATYPE_UNKNOWN;

                                        switch(bertag & LBER_ENCODING_MASK) {
                                        case LBER_PRIMITIVE:
                                                dI("Found primitive value, bertag = %u", bertag);
						break;
                                        case LBER_CONSTRUCTED:
                                                dW("Don't know how to handle LBER_CONSTRUCTED values");
						/* FALLTHROUGH */
                                        default:
                                                dW("Skipping attribute value, bertag = %u", bertag);
                                                continue;
                                        }

                                        assume_d(bertag & LBER_PRIMITIVE, NULL);

                                        switch(bertag & LBER_BIG_TAG_MASK) {
                                        case LBER_BOOLEAN:
                                        {       /* LDAPTYPE_BOOLEAN */
                                                ber_int_t val = -1;

                                                if (ber_get_boolean(berelm, &val) == LBER_ERROR) {
                                                        dW("ber_get_boolean: LBER_ERROR");
                                                        /* XXX: set error status on field */
                                                        continue;
                                                }

                                                assume_d(val != -1, NULL);
                                                field = probe_ent_creat1("field", NULL, SEXP_number_newb_r(&se_tmp_mem, (bool)val));
                                                field_type = OVAL_DATATYPE_BOOLEAN;
                                                SEXP_free_r(&se_tmp_mem);
                                        }       break;
                                        case LBER_INTEGER:
                                        {       /* LDAPTYPE_INTEGER */
                                                ber_int_t val = -1;

                                                if (ber_get_int(berelm, &val) == LBER_ERROR) {
                                                        dW("ber_get_int: LBER_ERROR");
                                                        /* XXX: set error status on field */
                                                        continue;
                                                }

                                                field = probe_ent_creat1("field", NULL, SEXP_number_newi_r(&se_tmp_mem, (int)val));
                                                field_type = OVAL_DATATYPE_INTEGER;
                                                SEXP_free_r(&se_tmp_mem);
                                        }       break;
                                        case LBER_BITSTRING:
                                                /* LDAPTYPE_BIT_STRING */
                                                dW("LBER_BITSTRING: not implemented");
                                                continue;
                                        case LBER_OCTETSTRING:
                                        {       /*
                                                 * LDAPTYPE_PRINTABLE_STRING
                                                 * LDAPTYPE_NUMERIC_STRING
                                                 * LDAPTYPE_DN_STRING
                                                 * LDAPTYPE_BINARY (?)
                                                 */
                                                char *val = NULL;

                                                if (ber_get_stringa(berelm, &val) == LBER_ERROR) {
                                                        dW("ber_get_stringa: LBER_ERROR");
                                                        /* XXX: set error status on field */
                                                        continue;
                                                }

                                                assume_d(val != NULL, NULL);
                                                field = probe_ent_creat1("field", NULL, SEXP_string_new_r(&se_tmp_mem, val, strlen(val)));
                                                field_type = OVAL_DATATYPE_STRING;
                                                SEXP_free_r(&se_tmp_mem);
                                                ber_memfree(val);
                                        }       break;
                                        case LBER_NULL:
                                                /* XXX: no equivalent LDAPTYPE_? or empty */
                                                dI("LBER_NULL: skipped");
                                                continue;
                                        case LBER_ENUMERATED:
                                                /* XXX: no equivalent LDAPTYPE_? */
                                                dW("Don't know how to handle LBER_ENUMERATED type");
                                                continue;
                                        default:
                                                dW("Unknown attribute value type, bertag = %u", bertag);
                                                continue;
                                        }

                                        if (field != NULL) {
                                                assume_d(field_type != OVAL_DATATYPE_UNKNOWN, NULL);

                                                probe_ent_setdatatype(field, field_type);
                                                probe_ent_attr_add(field, "name", SEXP_string_new_r(&se_tmp_mem, attr, strlen(attr)));
                                                SEXP_list_add(se_value, field);
                                                SEXP_free_r(&se_tmp_mem);
                                                SEXP_free(field);
                                        }
                                }

                                ber_sockbuf_free(berbuf);

                                /*
                                 * Create the item
                                 */
                                item = probe_item_create(OVAL_INDEPENDENT_LDAP57, NULL,
                                                         "suffix",       OVAL_DATATYPE_STRING, suffix,
                                                         "relative_dn",  OVAL_DATATYPE_STRING, relative_dn, /* XXX: pattern match */
                                                         "attribute",    OVAL_DATATYPE_STRING, attr,
                                                         "object_class", OVAL_DATATYPE_STRING, "",
                                                         "ldaptype",     OVAL_DATATYPE_STRING, "",
                                                         NULL);

                                SEXP_list_add(item, se_value);
                                SEXP_free(se_value);

                                probe_item_collect(ctx, item);

                                attr = ldap_next_attribute(ldp, entry, berelm);
                        }

                        ber_free(berelm, 0);
                        ldap_memfree(entry_dn);

                        entry    = ldap_next_entry(ldp, entry);
                        entry_dn = ldap_get_dn(ldp, entry);
                }

                /*
                 * Close the LDAP connection and free resources
                 */
                ldap_unbind_ext_s(ldp, NULL, NULL);
        }

        ldap_memfree(uri_list);

fail0:
        SEXP_free(se_suffix);
        SEXP_free(se_relative_dn);
        SEXP_free(se_attribute);

        free(suffix);
        free(relative_dn);
        free(attrs[1]); /* attribute */

        return (0);
}