示例#1
0
/*
 * mountd now keeps an open fd for the etab at all times to make sure that the
 * inode number changes when the xtab_export_write is done. If you change the
 * routine below such that the files are edited in place, then you'll need to
 * fix the auth_reload logic as well...
 */
static int
xtab_write(char *xtab, char *xtabtmp, char *lockfn, int is_export)
{
	struct exportent	xe;
	nfs_export		*exp;
	int			lockid, i;

	if ((lockid = xflock(lockfn, "w")) < 0) {
		xlog(L_ERROR, "can't lock %s for writing", xtab);
		return 0;
	}
	setexportent(xtabtmp, "w");

	for (i = 0; i < MCL_MAXTYPES; i++) {
		for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
			if (is_export && !exp->m_xtabent)
				continue;
			if (!is_export && ! exp->m_exported)
				continue;

			/* write out the export entry using the FQDN */
			xe = exp->m_export;
			xe.e_hostname = exp->m_client->m_hostname;
			putexportent(&xe);
		}
	}
	endexportent();

	cond_rename(xtabtmp, xtab);

	xfunlock(lockid);

	return 1;
}
示例#2
0
void
xtab_append(nfs_export *exp)
{
	struct exportent xe;
	int		lockid;

	if ((lockid = xflock(_PATH_XTABLCK, "w")) < 0)
		return;
	setexportent(_PATH_XTAB, "a");
	xe = exp->m_export;
	xe.e_hostname = exp->m_client->m_hostname;
	putexportent(&xe);
	endexportent();
	xfunlock(lockid);
	exp->m_xtabent = 1;
}
示例#3
0
int
rmtab_read(void)
{
	struct rmtabent		*rep;

	setrmtabent("r");
	while ((rep = getrmtabent(1, NULL)) != NULL) {
		int			htype;

		htype = client_gettype(rep->r_client);
		if (htype == MCL_FQDN || htype == MCL_SUBNETWORK)
			rmtab_read_wildcard(rep);
	}

	if (errno == EINVAL) {
		/* Something goes wrong. We need to fix the rmtab
		   file. */
		int	lockid;
		FILE	*fp;
		if ((lockid = xflock(_PATH_RMTABLCK, "w")) < 0)
			return -1;
		rewindrmtabent();
		if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) {
			endrmtabent ();
			xfunlock(lockid);
			return -1;
		}
		while ((rep = getrmtabent(0, NULL)) != NULL) {
			fputrmtabent(fp, rep, NULL);
		}
		if (rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
			xlog(L_ERROR, "couldn't rename %s to %s",
			     _PATH_RMTABTMP, _PATH_RMTAB);
		}
		endrmtabent();
		fendrmtabent(fp);
		xfunlock(lockid);
	}
	else {
		endrmtabent();
	}
	return 0;
}
示例#4
0
void
mountlist_del_all(const struct sockaddr *sap)
{
	char		*hostname;
	struct rmtabent	*rep;
	FILE		*fp;
	int		lockid;

	if ((lockid = xflock(_PATH_RMTABLCK, "w")) < 0)
		return;
	hostname = host_canonname(sap);
	if (hostname == NULL) {
		char buf[INET6_ADDRSTRLEN];
		xlog(L_ERROR, "can't get hostname of %s",
			host_ntop(sap, buf, sizeof(buf)));
		goto out_unlock;
	}

	if (!setrmtabent("r"))
		goto out_free;

	if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w")))
		goto out_close;

	while ((rep = getrmtabent(1, NULL)) != NULL) {
		if (strcmp(rep->r_client, hostname) == 0 &&
		    auth_authenticate("umountall", sap, rep->r_path) != NULL)
			continue;
		fputrmtabent(fp, rep, NULL);
	}
	if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
		xlog(L_ERROR, "couldn't rename %s to %s",
				_PATH_RMTABTMP, _PATH_RMTAB);
	}
	fendrmtabent(fp);
out_close:
	endrmtabent();	/* close & unlink */
out_free:
	free(hostname);
out_unlock:
	xfunlock(lockid);
}
示例#5
0
static int
xtab_read(char *xtab, char *lockfn, int is_export)
{
    /* is_export == 0  => reading /proc/fs/nfs/exports - we know these things are exported to kernel
     * is_export == 1  => reading /var/lib/nfs/etab - these things are allowed to be exported
     * is_export == 2  => reading /var/lib/nfs/xtab - these things might be known to kernel
     */
	struct exportent	*xp;
	nfs_export		*exp;
	int			lockid;

	if ((lockid = xflock(lockfn, "r")) < 0)
		return 0;
	setexportent(xtab, "r");
	if (is_export == 1)
		v4root_needed = 1;
	while ((xp = getexportent(is_export==0, 0)) != NULL) {
		if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
		    !(exp = export_create(xp, is_export!=1))) {
			continue;
		}
		switch (is_export) {
		case 0:
			exp->m_exported = 1;
			break;
		case 1:
			exp->m_xtabent = 1;
			exp->m_mayexport = 1;
			if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
				v4root_needed = 0;
			break;
		case 2:
			exp->m_exported = -1;/* may be exported */
			break;
		}
	}
	endexportent();
	xfunlock(lockid);

	return 0;
}
示例#6
0
void
mountlist_add(char *host, const char *path)
{
	struct rmtabent	xe;
	struct rmtabent	*rep;
	int		lockid;
	long		pos;

	if ((lockid = xflock(_PATH_RMTABLCK, "a")) < 0)
		return;
	setrmtabent("r+");
	while ((rep = getrmtabent(1, &pos)) != NULL) {
		if (strcmp (rep->r_client,
			    host) == 0
		    && strcmp(rep->r_path, path) == 0) {
			rep->r_count++;
			/* PRC: do the HA callout: */
			ha_callout("mount", rep->r_client, rep->r_path, rep->r_count);
			putrmtabent(rep, &pos);
			endrmtabent();
			xfunlock(lockid);
			return;
		}
	}
	endrmtabent();
	strncpy(xe.r_client, host,
		sizeof (xe.r_client) - 1);
	xe.r_client [sizeof (xe.r_client) - 1] = '\0';
	strncpy(xe.r_path, path, sizeof (xe.r_path) - 1);
	xe.r_path [sizeof (xe.r_path) - 1] = '\0';
	xe.r_count = 1;
	if (setrmtabent("a")) {
		/* PRC: do the HA callout: */
		ha_callout("mount", xe.r_client, xe.r_path, xe.r_count);
		putrmtabent(&xe, NULL);
		endrmtabent();
	}
	xfunlock(lockid);
}
示例#7
0
void
mountlist_del(char *hname, const char *path)
{
	struct rmtabent	*rep;
	FILE		*fp;
	int		lockid;
	int		match;

	if ((lockid = xflock(_PATH_RMTABLCK, "w")) < 0)
		return;
	if (!setrmtabent("r")) {
		xfunlock(lockid);
		return;
	}
	if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) {
		endrmtabent();
		xfunlock(lockid);
		return;
	}
	while ((rep = getrmtabent(1, NULL)) != NULL) {
		match = !strcmp (rep->r_client, hname)
			&& !strcmp(rep->r_path, path);
		if (match) {
			rep->r_count--;
			/* PRC: do the HA callout: */
			ha_callout("unmount", rep->r_client, rep->r_path, rep->r_count);
		}
		if (!match || rep->r_count)
			fputrmtabent(fp, rep, NULL);
	}
	if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
		xlog(L_ERROR, "couldn't rename %s to %s",
				_PATH_RMTABTMP, _PATH_RMTAB);
	}
	endrmtabent();	/* close & unlink */
	fendrmtabent(fp);
	xfunlock(lockid);
}
示例#8
0
文件: dspoolout.c 项目: jpmens/diablo
int
spool_file(char *spoolFile, int pass, NewslinkInfo *li, int flags)
{
    char seqFile[256];
    char newFile[256];
    char obIpBuf[256];
    char *outboundIpStr = OutboundIpStr;
    int begSeq = 0;
    int endSeq = 0;
    long newTime = 0;
    char portBuf[32];
    char logartsStr[MAXLOGARTS+2];
    int fd;
    struct stat st;
    char txBufSizeStr[32];
    char rxBufSizeStr[32];
    char TOSStr[32];
    char maxStreamStr[32];
    char compressStr[32];
    char delayStr[32];

    if (VerboseOpt)
	printf("spool_file(%s, %d, %s, %d)\n",
			spoolFile, pass, li->li_HostName, flags);
    /*
     * Initialize rx/txBufSizeStr
     */

    sprintf(txBufSizeStr, "-nop");
    sprintf(rxBufSizeStr, "-nop");
    sprintf(TOSStr, "-nop");
    sprintf(maxStreamStr, "-nop");
    sprintf(compressStr, "-nop");
    sprintf(delayStr, "-nop");

    if (li->li_TransmitBuf > 0 && li->li_TransmitBuf < 16 * 1024 * 1024)
	sprintf(txBufSizeStr, "-T%d", li->li_TransmitBuf);
    if (li->li_ReceiveBuf > 0 && li->li_ReceiveBuf < 16 * 1024 * 1024)
	sprintf(rxBufSizeStr, "-R%d", li->li_ReceiveBuf);
    if (li->li_TOS > 0 && li->li_TOS <= 0xff )
	sprintf(TOSStr, "-Q%d", li->li_TOS);
    if (li->li_MaxStream > 0)
	sprintf(maxStreamStr, "-M%d", li->li_MaxStream);
    if (li->li_Compress > 0)
	sprintf(compressStr, "-Z%d", li->li_Compress);
    if (li->li_DelayFeed > 0)
	sprintf(delayStr, "-W%d", li->li_DelayFeed);

    /*
     * Outbound article logging.
     */
    sprintf(logartsStr, "-nop");
    if (li->li_LogArts && *li->li_LogArts) {
	strcpy(logartsStr, "-A");
	StrnCpyNull(logartsStr+2, li->li_LogArts, MAXLOGARTS);
    }

    /*
     * Override outbound IP
     */

    if (li->li_BindAddress != NULL &&
			strlen(li->li_BindAddress) < sizeof(obIpBuf) - 8) {
	sprintf(obIpBuf, "-B%s", li->li_BindAddress);
	outboundIpStr = obIpBuf;
    }

    if (li->li_Port <= 0)
	li->li_Port = 119;
    sprintf(portBuf, "%d", li->li_Port);

    sprintf(seqFile, ".%s.seq", spoolFile);

    /*
     * Get beginning and ending sequence numbers
     */

    fd = open(seqFile, O_RDWR|O_CREAT, 0600);

    if (fd >= 0) {
	char buf[64];

	xflock(fd, XLOCK_EX);		/* lock and leave locked */
	memset(buf, 0, sizeof(buf));
	read(fd, buf, sizeof(buf) - 1);
	sscanf(buf, "%d %d %lx", &begSeq, &endSeq, &newTime);
    }

    /*
     * Discard beginning sequence numbers that are now deleted, or
     * delete queue files that are too old.
     */

    while (begSeq < endSeq) {
	sprintf(newFile, "%s.S%05d", spoolFile, begSeq);
	if (li->li_MaxQueueFile > 0 && begSeq < endSeq - li->li_MaxQueueFile)
	    remove(newFile);
	if (stat(newFile, &st) == 0)
	    break;
	++begSeq;
    }

    /*
     * If primary spool file exists, shift to primary
     * queue
     */

    if (pass == 1) {
	{
	    int tries = 100;
	    int32 dt;
	    struct stat st;

	    while (tries > 0) {
		sprintf(newFile, "%s.S%05d", spoolFile, endSeq);
		if (stat(newFile, &st) < 0)
		    break;
		--tries;
		++endSeq;
	    }

	    /*
	     * Only create a new spool file if:
	     *
	     * (1) endSeq == begSeq + 1, or
	     * (2) current time larger then newTime + MinFlushSecs
	     * (3) there is time weirdness
	     */

	    dt = time(NULL) - ((int32)newTime + MinFlushSecs);

	    if (VerboseOpt)
		printf("PASS %d: dt=%d tries=%d begSeq=%d endSeq=%d\n",
			pass, dt, tries, begSeq, endSeq);

	    if (endSeq <= begSeq + 4 || dt > 0 || dt < -MinFlushSecs) {
		/*
		 * If a dnewslink has a lock on the unsequenced spool file,
		 * clear the SF_REALTIME flag... a realtime dnewslink is
		 * already running so there is no sense trying to start 
		 * another one.
		 */
		if (flags & SF_REALTIME) {
		    int tfd;

		    if ((tfd = open(spoolFile, O_RDWR)) >= 0) {
			if (xflock(tfd, XLOCK_EX|XLOCK_NB) < 0) {
			    if (VerboseOpt)
				printf("%s: realtime already\n", spoolFile);
			    flags &= ~SF_REALTIME;
			}
			close(tfd);
		    }
		}

		if (stat(spoolFile, &st) == 0 && st.st_size > 0 &&
					rename(spoolFile, newFile) == 0) {
		    ++endSeq;
		    if (!Quiet)
			printf("dspoolout: add %s\n", newFile);
		} else {
		    if (VerboseOpt && !Quiet)
			printf("dspoolout: nofile %s\n", newFile);
		    if (endSeq == begSeq)
			AddNode(spoolFile);
		}
		if (flags & SF_REALTIME) {
		    int fd = xopen(O_RDWR|O_CREAT, 0644, spoolFile);
		    if (fd != -1) {
			close(fd);
		    }
		}
		newTime = time(NULL);
	    } else {
		AddNode(spoolFile);
		if (VerboseOpt && !Quiet)
		    printf("dspoolout: wait %s\n", spoolFile);
	    }
	}

	/*
	 * Update sequence number file
	 */

	if (fd >= 0) {
	    char buf[64];

	    sprintf(buf, "%5d %5d %08lx\n", begSeq, endSeq, newTime);
	    lseek(fd, 0L, 0);
	    write(fd, buf, strlen(buf));
	    ftruncate(fd, lseek(fd, 0L, 1));
	}
    }

    if (fd >= 0) {
	xflock(fd, XLOCK_UN);
	close(fd);
    }

    /*
     * Run up to N newslink's/innxmit's, usually set at 2.
     *
     * Note that we spool out the queue as a FIFO.  This is important as
     * it reduces article jumble.
     */

    if (pass == 2 && FindNode(spoolFile) == NULL) {
	int tries = li->li_MaxParallel;
	int look;

	/*
	 * Start up to MaxParallel dnewslinks.  If the nobatch
	 * flag is set, do not start any.
	 */

	if (flags & SF_NOBATCH)
	    tries = 0;

	for (look = 0; look < 32 && tries &&
			begSeq + look < endSeq - li->li_QueueSkip; ++look) {
	    int use = begSeq + look;
	    int fd;
	    char numBuf[32];

	    {
		int left = endSeq - use - li->li_QueueSkip;
		if (left > 32)
		    left = 32;
		if (left < 3 && li->li_QueueSkip == 0)
		    left = 3;
		else if (left < 1)
		    left = 1;
		sprintf(numBuf, "%d", left);
	    if (VerboseOpt)
		printf("PASS %d: look=%d tries=%d begSeq=%d endSeq=%d use=%d left=%d\n",
			pass, look, tries, begSeq, endSeq, use, left);
	    }


	    sprintf(newFile, "%s.S%05d", spoolFile, use);

	    if ((fd = open(newFile, O_RDWR)) >= 0) {
		if (xflock(fd, XLOCK_EX|XLOCK_NB) == 0) {
		    char seqName[64];
		    char templateFile[256];

		    xflock(fd, XLOCK_UN);

		    if (!Quiet)
			printf("dspoolout: run %s.S%05d\n", spoolFile, use);

		    sprintf(templateFile, "%s.S%%05d", spoolFile);
		    sprintf(seqName, "%d", use);
		    if (VerboseOpt)
			    printf("%s %s%s %s%s %s%s %s%s %s%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
				"dnewslink",
				"-h", li->li_HostName,
				"-b", templateFile,
				"-S", seqName,
				"-N", numBuf,
				"-P", portBuf,
				"-D",
				((flags & SF_NOSTREAM) ? "-i" : "-nop"),
				((flags & SF_HEADFEED) ?
				    ((flags & SF_PRESBYTES) ? "-HB" : "-H") :
				    "-nop"),
				((flags & SF_NOCHECK) ? "-I" : "-nop"),
				((flags & SF_GENLINES) ? "-L" : "-nop"),
				((flags & SF_ARTSTAT) ? "-x" : "-nop"),
				compressStr,
				logartsStr,
				outboundIpStr,
				txBufSizeStr,
				rxBufSizeStr,
				TOSStr,
				delayStr,
				maxStreamStr
			    );
		    if (ForReal && fork() == 0) {
			char binPath[128];

			if (li->li_StartDelay > 0) {
			    if (xflock(fd, XLOCK_EX|XLOCK_NB) == 0) {
				sleep(li->li_StartDelay);
				xflock(fd, XLOCK_UN);
			    } else {
				if (DebugOpt)
				    printf(" qfile already locked for delay\n");
				exit(0);
			    }
			}

			if (li->li_Priority > 0)
			    nice(li->li_Priority);

			snprintf(binPath, sizeof(binPath), "%s/dbin/dnewslink", NewsHome);

			    execl(binPath, "dnewslink",
				"-h", li->li_HostName,
				"-b", templateFile,
				"-S", seqName,
				"-N", numBuf,
				"-P", portBuf,
				"-D",
				((flags & SF_NOSTREAM) ? "-i" : "-nop"),
				((flags & SF_HEADFEED) ?
				    ((flags & SF_PRESBYTES) ? "-HB" : "-H") :
				    "-nop"),
				((flags & SF_NOCHECK) ? "-I" : "-nop"),
				((flags & SF_GENLINES) ? "-L" : "-nop"),
				((flags & SF_ARTSTAT) ? "-x" : "-nop"),
				compressStr,
				logartsStr,
				outboundIpStr,
				txBufSizeStr,
				rxBufSizeStr,
				TOSStr,
				delayStr,
				maxStreamStr,
				NULL
			    );
			exit(0);
		    }
		}
		--tries;	/* even if lock fails */
		close(fd);
	    }
	}

	/*
	 * Deal with the realtime dnewslink, but only if:
	 *	The realtime flag is set
	 *	We have not gotten behind
	 *	We did not detect another realtime process
	 */

	if (VerboseOpt)
	    printf("%s: flags %02x nseq %d\n", spoolFile, flags & SF_REALTIME, endSeq-begSeq);

	if ((flags & SF_REALTIME) &&
				(ForceRealTime || (endSeq - begSeq <= 2))) {
	    int fd;

	    if ((fd = open(spoolFile, O_RDWR|O_CREAT, 0600)) >= 0) {
		if (xflock(fd, XLOCK_EX|XLOCK_NB) == 0) {
		    xflock(fd, XLOCK_UN);

		    if (!Quiet)
			printf("dspoolout: run realtime %s\n", spoolFile);

		    if (VerboseOpt)
			printf("%s %s%s %s%s %s%s %s%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
				"dnewslink",
				"-h", li->li_HostName,
				"-b", spoolFile,
				"-P", portBuf,
				"-N", "100",	/* 1000 spool cycles	*/
				((li->li_StartDelay < 0) ? "-r-1" : "-r"),
				((flags & SF_NOTIFY) ? "-o" : "-nop"),
				((flags & SF_NOTIFY) ? spoolFile : "-nop"),
				((flags & SF_NOSTREAM) ? "-i" : "-nop"),
				((flags & SF_HEADFEED) ?
				    ((flags & SF_PRESBYTES) ? "-HB" : "-H") :
				    "-nop"),
				(((flags & SF_NOCHECK)||(li->li_Check==2)) ? "-I" : "-nop"),
				((flags & SF_GENLINES) ? "-L" : "-nop"),
				((flags & SF_ARTSTAT) ? "-x" : "-nop"),
				compressStr,
				logartsStr,
				outboundIpStr,
				txBufSizeStr,
				rxBufSizeStr,
				delayStr,
				maxStreamStr
			    );
		    if (ForReal && fork() == 0) {
			char binPath[128];

			if (li->li_StartDelay > 0)
			    sleep(li->li_StartDelay);

			if (li->li_Priority > 0)
			    nice(li->li_Priority);

			snprintf(binPath, sizeof(binPath), "%s/dbin/dnewslink", NewsHome);

			    /*
			     * realtime option is '-r'.  If a delay of -1
			     * is specified, we pass -r-1 to dnewslink which
			     * reduces the tail latency from 1 second to 1ms.
			     */
			    execl(binPath, "dnewslink", 
				"-h", li->li_HostName,
				"-b", spoolFile,
				"-P", portBuf,
				"-N", "100",	/* 1000 spool cycles	*/
				((li->li_StartDelay < 0) ? "-r-1" : "-r"),
				((flags & SF_NOTIFY) ? "-o" : "-nop"),
				((flags & SF_NOTIFY) ? spoolFile : "-nop"),
				((flags & SF_NOSTREAM) ? "-i" : "-nop"),
				((flags & SF_HEADFEED) ?
				    ((flags & SF_PRESBYTES) ? "-HB" : "-H") :
				    "-nop"),
				(((flags & SF_NOCHECK)||(li->li_Check==2)) ? "-I" : "-nop"),
				((flags & SF_GENLINES) ? "-L" : "-nop"),
				((flags & SF_ARTSTAT) ? "-x" : "-nop"),
				compressStr,
				logartsStr,
				outboundIpStr,
				txBufSizeStr,
				rxBufSizeStr,
				delayStr,
				maxStreamStr,
				NULL
			    );
			exit(0);
		    }
		}
		close(fd);
	    }
	}
    }
    return(flags);
}
示例#9
0
mountlist
mountlist_list(void)
{
	static mountlist	mlist = NULL;
	static time_t		last_mtime = 0;
	mountlist		m;
	struct rmtabent		*rep;
	struct stat		stb;
	int			lockid;

	if ((lockid = xflock(_PATH_RMTABLCK, "r")) < 0)
		return NULL;
	if (stat(_PATH_RMTAB, &stb) < 0) {
		xlog(L_ERROR, "can't stat %s: %s",
				_PATH_RMTAB, strerror(errno));
		xfunlock(lockid);
		return NULL;
	}
	if (stb.st_mtime != last_mtime) {
		mountlist_freeall(mlist);
		mlist = NULL;
		last_mtime = stb.st_mtime;

		setrmtabent("r");
		while ((rep = getrmtabent(1, NULL)) != NULL) {
			m = calloc(1, sizeof(*m));
			if (m == NULL) {
				mountlist_freeall(mlist);
				mlist = NULL;
				xlog(L_ERROR, "%s: memory allocation failed",
						__func__);
				break;
			}

			if (reverse_resolve) {
				struct addrinfo *ai;
				ai = host_pton(rep->r_client);
				if (ai != NULL) {
					m->ml_hostname = host_canonname(ai->ai_addr);
					freeaddrinfo(ai);
				}
			}
			if (m->ml_hostname == NULL)
				m->ml_hostname = strdup(rep->r_client);

			m->ml_directory = strdup(rep->r_path);

			if (m->ml_hostname == NULL || m->ml_directory == NULL) {
				mountlist_freeall(mlist);
				mlist = NULL;
				xlog(L_ERROR, "%s: memory allocation failed",
						__func__);
				break;
			}

			m->ml_next = mlist;
			mlist = m;
		}
		endrmtabent();
	}
	xfunlock(lockid);

	return mlist;
}