コード例 #1
0
ファイル: cluster.c プロジェクト: jarulraj/postgres95
void
copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
{
    Relation OldIndex, NewHeap;
    HeapTuple Old_pg_index_Tuple, Old_pg_index_relation_Tuple, pg_proc_Tuple;
    IndexTupleForm        Old_pg_index_Form;
    Form_pg_class	  Old_pg_index_relation_Form;
    Form_pg_proc          pg_proc_Form;
    char                 *NewIndexName;
    AttrNumber 		 *attnumP;
    int                   natts;
    FuncIndexInfo *       finfo;

    NewHeap  = heap_open(OIDNewHeap);
    OldIndex = index_open(OIDOldIndex);

    /*
     * OK. Create a new (temporary) index for the one that's already
     * here. To do this I get the info from pg_index, re-build the
     * FunctInfo if I have to, and add a new index with a temporary
     * name.
     */
    Old_pg_index_Tuple =
	SearchSysCacheTuple(INDEXRELID,
			    ObjectIdGetDatum(OldIndex->rd_id),
			    0,0,0);

    Assert(Old_pg_index_Tuple);
    Old_pg_index_Form = (IndexTupleForm)GETSTRUCT(Old_pg_index_Tuple);

    Old_pg_index_relation_Tuple =
	SearchSysCacheTuple(RELOID,
			    ObjectIdGetDatum(OldIndex->rd_id),
			    0,0,0);

    Assert(Old_pg_index_relation_Tuple);
    Old_pg_index_relation_Form =
	(Form_pg_class)GETSTRUCT(Old_pg_index_relation_Tuple);

     NewIndexName = palloc(NAMEDATALEN+1);  /* XXX */
     sprintf(NewIndexName, "temp_%x", OIDOldIndex); /* Set the name. */

    /*
     * Ugly as it is, the only way I have of working out the number of
     * attribues is to count them. Mostly there'll be just one but 
     * I've got to be sure.
     */
    for (attnumP = &(Old_pg_index_Form->indkey[0]), natts = 0;
	 *attnumP != InvalidAttrNumber;
	 attnumP++, natts++);

    /*
     * If this is a functional index, I need to rebuild the functional
     * component to pass it to the defining procedure.
     */
    if (Old_pg_index_Form->indproc != InvalidOid) {
	FIgetnArgs(finfo) = natts;
	FIgetProcOid(finfo) = Old_pg_index_Form->indproc;

	pg_proc_Tuple =
	    SearchSysCacheTuple(PROOID,
				ObjectIdGetDatum(Old_pg_index_Form->indproc),
				0,0,0);

	Assert(pg_proc_Tuple);
	pg_proc_Form = (Form_pg_proc)GETSTRUCT(pg_proc_Tuple);
	namecpy(&(finfo->funcName), &(pg_proc_Form->proname));
    } else {
	finfo = (FuncIndexInfo *) NULL;
	natts = 1;
    }

    index_create((NewHeap->rd_rel->relname).data,
		 NewIndexName, 
		 finfo,
		 Old_pg_index_relation_Form->relam,
		 natts, 
		 Old_pg_index_Form->indkey,
		 Old_pg_index_Form->indclass,
		 (uint16)0, (Datum) NULL, NULL);

    heap_close(OldIndex);
    heap_close(NewHeap);
}
コード例 #2
0
ファイル: slotfuncs.c プロジェクト: eydunn/postgres
/*
 * pg_get_replication_slots - SQL SRF showing active replication slots.
 */
Datum
pg_get_replication_slots(PG_FUNCTION_ARGS)
{
#define PG_GET_REPLICATION_SLOTS_COLS 10
	ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
	TupleDesc	tupdesc;
	Tuplestorestate *tupstore;
	MemoryContext per_query_ctx;
	MemoryContext oldcontext;
	int			slotno;

	/* check to see if caller supports us returning a tuplestore */
	if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("set-valued function called in context that cannot accept a set")));
	if (!(rsinfo->allowedModes & SFRM_Materialize))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("materialize mode required, but it is not " \
						"allowed in this context")));

	/* Build a tuple descriptor for our result type */
	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
		elog(ERROR, "return type must be a row type");

	/*
	 * We don't require any special permission to see this function's data
	 * because nothing should be sensitive. The most critical being the slot
	 * name, which shouldn't contain anything particularly sensitive.
	 */

	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
	oldcontext = MemoryContextSwitchTo(per_query_ctx);

	tupstore = tuplestore_begin_heap(true, false, work_mem);
	rsinfo->returnMode = SFRM_Materialize;
	rsinfo->setResult = tupstore;
	rsinfo->setDesc = tupdesc;

	MemoryContextSwitchTo(oldcontext);

	for (slotno = 0; slotno < max_replication_slots; slotno++)
	{
		ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[slotno];
		Datum		values[PG_GET_REPLICATION_SLOTS_COLS];
		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS];

		TransactionId xmin;
		TransactionId catalog_xmin;
		XLogRecPtr	restart_lsn;
		XLogRecPtr	confirmed_flush_lsn;
		pid_t		active_pid;
		Oid			database;
		NameData	slot_name;
		NameData	plugin;
		int			i;

		SpinLockAcquire(&slot->mutex);
		if (!slot->in_use)
		{
			SpinLockRelease(&slot->mutex);
			continue;
		}
		else
		{
			xmin = slot->data.xmin;
			catalog_xmin = slot->data.catalog_xmin;
			database = slot->data.database;
			restart_lsn = slot->data.restart_lsn;
			confirmed_flush_lsn = slot->data.confirmed_flush;
			namecpy(&slot_name, &slot->data.name);
			namecpy(&plugin, &slot->data.plugin);

			active_pid = slot->active_pid;
		}
		SpinLockRelease(&slot->mutex);

		memset(nulls, 0, sizeof(nulls));

		i = 0;
		values[i++] = NameGetDatum(&slot_name);

		if (database == InvalidOid)
			nulls[i++] = true;
		else
			values[i++] = NameGetDatum(&plugin);

		if (database == InvalidOid)
			values[i++] = CStringGetTextDatum("physical");
		else
			values[i++] = CStringGetTextDatum("logical");

		if (database == InvalidOid)
			nulls[i++] = true;
		else
			values[i++] = database;

		values[i++] = BoolGetDatum(active_pid != 0);

		if (active_pid != 0)
			values[i++] = Int32GetDatum(active_pid);
		else
			nulls[i++] = true;

		if (xmin != InvalidTransactionId)
			values[i++] = TransactionIdGetDatum(xmin);
		else
			nulls[i++] = true;

		if (catalog_xmin != InvalidTransactionId)
			values[i++] = TransactionIdGetDatum(catalog_xmin);
		else
			nulls[i++] = true;

		if (restart_lsn != InvalidXLogRecPtr)
			values[i++] = LSNGetDatum(restart_lsn);
		else
			nulls[i++] = true;

		if (confirmed_flush_lsn != InvalidXLogRecPtr)
			values[i++] = LSNGetDatum(confirmed_flush_lsn);
		else
			nulls[i++] = true;

		tuplestore_putvalues(tupstore, tupdesc, values, nulls);
	}

	tuplestore_donestoring(tupstore);

	return (Datum) 0;
}
コード例 #3
0
ファイル: sfsops.c プロジェクト: gildafnai82/craq
/* Return -1 on error, 0 otherwise */
int
sfs_stat2names (sfs_names *snp, const struct stat *sb)
{


  const char *fs;
  int cdfd;
  sfsctl_getidnames_res res;
  struct passwd *pw;
  struct group *gr;
  bool_t remote = FALSE;

  bool_t uname = FALSE;
  bool_t gname = FALSE;
  struct id_dat *id_elm;
  struct id_cache *ic;
  u_int hval;

  ic = lookup_ic (sb->st_dev);
  
  if (!ic)
    return -1;

  for (id_elm = id2name_chain (&ic->uidtab, sb->st_uid); 
       id_elm && (sb->st_uid != id_elm->id);
       id_elm = id2name_next (id_elm))
    ;
  if (id_elm)
    {	 
      namecpy (snp->uidname, id_elm->name);
      uname = TRUE;
    }


  for (id_elm = id2name_chain (&ic->gidtab, sb->st_gid); 
       id_elm && (sb->st_gid != id_elm->id);
       id_elm = id2name_next (id_elm))
    ;
  if (id_elm)
    {	 
      namecpy (snp->gidname, id_elm->name);
      gname = TRUE;
    }


  if (gname && uname)
    return 0;

  bzero (&res, sizeof (res));
  if (devcon_lookup (&cdfd, &fs, sb->st_dev)) {
    sfsctl_getidnames_arg arg;
    remote = TRUE;
    arg.filesys = (char *) fs;
    arg.nums.uid = sb->st_uid;
    arg.nums.gid = sb->st_gid;
    srpc_call (&sfsctl_prog_1, cdfd, SFSCTL_GETIDNAMES, &arg, &res);
  }

  if (!uname)
    {
      pw = getpwuid (sb->st_uid);
      if (remote && !res.status && res.u.names.uidname.present) {
	if (pw && !strcmp (pw->pw_name, res.u.names.uidname.u.name))
	  namecpy (snp->uidname, pw->pw_name);
	else {
	  snp->uidname[0] = '%';
	  namecpy (snp->uidname + 1, res.u.names.uidname.u.name);
	}
      }
      else if (!remote && pw)
	namecpy (snp->uidname, pw->pw_name);
      else
	sprintf (snp->uidname, "%u", (int) sb->st_uid);

      id_elm = malloc (sizeof (*id_elm));

      if (!id_elm)
	{
	  xdr_free ((xdrproc_t) xdr_sfsctl_getidnames_res, (char *) &res);
	  return -1;
	}

      bzero (id_elm->name, sizeof (id_elm->name));
      namecpy (id_elm->name, snp->uidname);
      id_elm->id = sb->st_uid;
      hval = hash_string (id_elm->name);

      id2name_insert (&ic->uidtab,   id_elm, id_elm->id);
      name2id_insert (&ic->unametab, id_elm, hval);
    }

  if (!gname)
    {
      gr = getgrgid (sb->st_gid);
      if (remote && !res.status && res.u.names.gidname.present) {
	if (gr && !strcmp (gr->gr_name, res.u.names.gidname.u.name))
	  namecpy (snp->gidname, gr->gr_name);
	else {
	  snp->gidname[0] = '%';
	  namecpy (snp->gidname + 1, res.u.names.gidname.u.name);
	}
      }
      else if (!remote && gr)
	namecpy (snp->gidname, gr->gr_name);
      else
	sprintf (snp->gidname, "%u", (int) sb->st_gid);

      id_elm = malloc (sizeof (*id_elm));

      if (!id_elm)
	{
	  xdr_free ((xdrproc_t) xdr_sfsctl_getidnames_res, (char *) &res);
	  return -1;
	}

      bzero (id_elm->name, sizeof (id_elm->name));
      namecpy (id_elm->name, snp->gidname);
      id_elm->id = sb->st_gid;
      hval = hash_string (id_elm->name);

      id2name_insert (&ic->gidtab,   id_elm, id_elm->id);
      name2id_insert (&ic->gnametab, id_elm, hval);
    }

  xdr_free ((xdrproc_t) xdr_sfsctl_getidnames_res, (char *) &res);
  return 0;
}
コード例 #4
0
ファイル: sfsops.c プロジェクト: gildafnai82/craq
int
lookup_id (struct id_cache *ic, bool_t gid, char *name)
{
  struct id_dat *id_elm;
  char *orig_name = name;
  const char *fs;
  int cdfd;
  u_int hval;

  if (*name == '%')
    name++;

  hval = hash_string (name);

  for (id_elm = name2id_chain ((gid ? &ic->gnametab : &ic->unametab), 
			       hval); 
       id_elm && strcmp (name, id_elm->name);
       id_elm = name2id_next (id_elm))
    ;
  if (id_elm)
    return id_elm->id;

  id_elm = malloc (sizeof (*id_elm));
  if (!id_elm)
    return -1;

  bzero (id_elm->name, sizeof (id_elm->name));
  namecpy (id_elm->name, name);

  name = orig_name;

  /* Get the id either locally or via SFS */
  if (*name != '%' || (++name, !devcon_lookup (&cdfd, &fs, ic->dev))) {
    if (gid) {
      struct group *gr = getgrnam (name);
      if (gr)
	id_elm->id = gr->gr_gid;
      else
	id_elm->id = -1;
    }
    else {
      struct passwd *pw = getpwnam (name);
      if (pw)
	id_elm->id = pw->pw_uid;
      else 
	id_elm->id = -1;
    }
  }
  else if (strlen (name) > sfs_idnamelen)
    {
      free (id_elm);
      return -1;
    }
  else {

    sfsctl_getidnums_arg arg;
    sfsctl_getidnums_res res;
    sfs_opt_idname *sid;

    bzero (&arg, sizeof (arg));
    bzero (&res, sizeof (res));
    arg.filesys = (char *) fs;
    sid = gid ? &arg.names.gidname : &arg.names.uidname;
    sid->present = TRUE;
    sid->u.name = (char *) name;
    
    srpc_call (&sfsctl_prog_1, cdfd, SFSCTL_GETIDNUMS, &arg, &res);

    if (!res.status)
      id_elm->id = gid ? res.u.nums.gid : res.u.nums.uid;
    else {
      free (id_elm);
      xdr_free ((xdrproc_t) xdr_sfsctl_getidnums_res, (char *) &res);
      return -1;
    }

    
    xdr_free ((xdrproc_t) xdr_sfsctl_getidnums_res, (char *) &res);


  }

  id2name_insert (gid ? &ic->gidtab   : &ic->uidtab,   id_elm, id_elm->id);
  name2id_insert (gid ? &ic->gnametab : &ic->unametab, id_elm, hval);

  return id_elm->id;
}
コード例 #5
0
ファイル: pipe.c プロジェクト: ChunHungLiu/xenomai
int rt_pipe_create(RT_PIPE *pipe,
		   const char *name, int minor, size_t poolsize)
#endif
{
	struct rtipc_port_label plabel;
	struct sockaddr_ipc saddr;
	struct alchemy_pipe *pcb;
	struct service svc;
	size_t streambufsz;
	socklen_t addrlen;
	int ret, sock;

	if (threadobj_irq_p())
		return -EPERM;

	CANCEL_DEFER(svc);

	pcb = xnmalloc(sizeof(*pcb));
	if (pcb == NULL) {
		ret = -ENOMEM;
		goto out;
	}

	sock = __RT(socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP));
	if (sock < 0) {
		warning("RTIPC/XDDP protocol not supported by kernel");
		ret = -errno;
		xnfree(pcb);
		goto out;
	}

	if (name && *name) {
		namecpy(plabel.label, name);
		ret = __RT(setsockopt(sock, SOL_XDDP, XDDP_LABEL,
				      &plabel, sizeof(plabel)));
		if (ret)
			goto fail_sockopt;
	}

	if (poolsize > 0) {
		ret = __RT(setsockopt(sock, SOL_XDDP, XDDP_POOLSZ,
				      &poolsize, sizeof(poolsize)));
		if (ret)
			goto fail_sockopt;
	}

	streambufsz = ALCHEMY_PIPE_STREAMSZ;
	ret = __RT(setsockopt(sock, SOL_XDDP, XDDP_BUFSZ,
			      &streambufsz, sizeof(streambufsz)));
	if (ret)
		goto fail_sockopt;

	memset(&saddr, 0, sizeof(saddr));
	saddr.sipc_family = AF_RTIPC;
	saddr.sipc_port = minor;
	ret = __RT(bind(sock, (struct sockaddr *)&saddr, sizeof(saddr)));
	if (ret)
		goto fail_sockopt;

	if (minor == P_MINOR_AUTO) {
		/* Fetch the assigned minor device. */
		addrlen = sizeof(saddr);
		ret = __RT(getsockname(sock, (struct sockaddr *)&saddr, &addrlen));
		if (ret)
			goto fail_sockopt;
		if (addrlen != sizeof(saddr)) {
			ret = -EINVAL;
			goto fail_register;
		}
		minor = saddr.sipc_port;
	}

	generate_name(pcb->name, name, &pipe_namegen);
	pcb->sock = sock;
	pcb->minor = minor;
	pcb->magic = pipe_magic;

	if (syncluster_addobj(&alchemy_pipe_table, pcb->name, &pcb->cobj)) {
		ret = -EEXIST;
		goto fail_register;
	}

	pipe->handle = mainheap_ref(pcb, uintptr_t);

	CANCEL_RESTORE(svc);

	return minor;
fail_sockopt:
	ret = -errno;
	if (ret == -EADDRINUSE)
		ret = -EBUSY;
fail_register:
	__RT(close(sock));
	xnfree(pcb);
out:
	CANCEL_RESTORE(svc);

	return ret;	
}