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); }
/* * 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; }
/* 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; }
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; }
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; }