Blame gfs2/mkfs/metafs.c

Packit 6ef888
#include <stdlib.h>
Packit 6ef888
#include <string.h>
Packit 6ef888
#include <stdio.h>
Packit 6ef888
#include <unistd.h>
Packit 6ef888
#include <sys/file.h>
Packit 6ef888
#include <sys/types.h>
Packit 6ef888
#include <sys/stat.h>
Packit 6ef888
#include <sys/mount.h>
Packit 6ef888
#include <fcntl.h>
Packit 6ef888
#include <errno.h>
Packit 6ef888
#include <signal.h>
Packit 6ef888
#include <mntent.h>
Packit 6ef888
#include <libintl.h>
Packit 6ef888
#include <locale.h>
Packit 6ef888
#define _(String) gettext(String)
Packit 6ef888
Packit 6ef888
#include "metafs.h"
Packit 6ef888
Packit 6ef888
int metafs_interrupted;
Packit 6ef888
Packit 6ef888
static int lock_for_admin(struct metafs *mfs, int debug)
Packit 6ef888
{
Packit 6ef888
	int error;
Packit 6ef888
Packit 6ef888
	if (debug)
Packit 6ef888
		printf(_("Trying to get admin lock..."));
Packit 6ef888
Packit 6ef888
	mfs->fd = open(mfs->path, O_RDONLY | O_NOFOLLOW);
Packit 6ef888
	if (mfs->fd < 0)
Packit 6ef888
		return -1;
Packit 6ef888
Packit 6ef888
	error = flock(mfs->fd, LOCK_EX);
Packit 6ef888
	if (error) {
Packit 6ef888
		close(mfs->fd);
Packit 6ef888
		return -1;
Packit 6ef888
	}
Packit 6ef888
	if (debug)
Packit 6ef888
		printf(_("locked.\n"));
Packit 6ef888
	return 0;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static void sighandler(int error)
Packit 6ef888
{
Packit 6ef888
	metafs_interrupted = 1;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static void setsigs(void (*handler)(int))
Packit 6ef888
{
Packit 6ef888
	struct sigaction sa = {	.sa_handler = handler };
Packit 6ef888
Packit 6ef888
	sigaction(SIGINT, &sa, NULL);
Packit 6ef888
	sigaction(SIGILL, &sa, NULL);
Packit 6ef888
	sigaction(SIGTERM, &sa, NULL);
Packit 6ef888
	sigaction(SIGHUP, &sa, NULL);
Packit 6ef888
	sigaction(SIGABRT, &sa, NULL);
Packit 6ef888
	sigaction(SIGCONT, &sa, NULL);
Packit 6ef888
	sigaction(SIGUSR1, &sa, NULL);
Packit 6ef888
	sigaction(SIGUSR2, &sa, NULL);
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
int mount_gfs2_meta(struct metafs *mfs, const char *path, int debug)
Packit 6ef888
{
Packit 6ef888
	int ret;
Packit 6ef888
Packit 6ef888
	mfs->path = strdup("/tmp/.gfs2meta.XXXXXX");
Packit 6ef888
	if (mfs->path == NULL)
Packit 6ef888
		return -1;
Packit 6ef888
Packit 6ef888
	if(!mkdtemp(mfs->path))
Packit 6ef888
		goto err_free;
Packit 6ef888
Packit 6ef888
	setsigs(sighandler);
Packit 6ef888
Packit 6ef888
	ret = mount(path, mfs->path, "gfs2meta", 0, mfs->context);
Packit 6ef888
	if (ret)
Packit 6ef888
		goto err_rmdir;
Packit 6ef888
Packit 6ef888
	if (lock_for_admin(mfs, debug))
Packit 6ef888
		goto err_umount;
Packit 6ef888
Packit 6ef888
	return 0;
Packit 6ef888
Packit 6ef888
err_umount:
Packit 6ef888
	if (umount(mfs->path))
Packit 6ef888
		/* Translators: the first %s here is a path, the second is an error message */
Packit 6ef888
		fprintf(stderr, _("Could not unmount %s: %s\n"),
Packit 6ef888
		                    mfs->path, strerror(errno));
Packit 6ef888
	setsigs(SIG_DFL);
Packit 6ef888
err_rmdir:
Packit 6ef888
	rmdir(mfs->path);
Packit 6ef888
err_free:
Packit 6ef888
	free(mfs->path);
Packit 6ef888
	mfs->path = NULL;
Packit 6ef888
	return -1;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
void cleanup_metafs(struct metafs *mfs)
Packit 6ef888
{
Packit 6ef888
	int ret;
Packit 6ef888
Packit 6ef888
	if (mfs->fd <= 0)
Packit 6ef888
		return;
Packit 6ef888
Packit 6ef888
	fsync(mfs->fd);
Packit 6ef888
	close(mfs->fd);
Packit 6ef888
	ret = umount(mfs->path);
Packit 6ef888
	if (ret)
Packit 6ef888
		/* Translators: the first %s here is a path, the second is an error message */
Packit 6ef888
		fprintf(stderr, "Could not unmount %s : %s\n",
Packit 6ef888
			mfs->path, strerror(errno));
Packit 6ef888
	else
Packit 6ef888
		rmdir(mfs->path);
Packit 6ef888
Packit 6ef888
	setsigs(SIG_DFL);
Packit 6ef888
	metafs_interrupted = 0;
Packit 6ef888
Packit 6ef888
	free(mfs->path);
Packit 6ef888
	mfs->path = NULL;
Packit 6ef888
	free(mfs->context);
Packit 6ef888
	mfs->context = NULL;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
/**
Packit 6ef888
 * Returns a duplicate of the 'context' mount option, or NULL if not found.
Packit 6ef888
 */
Packit 6ef888
char *copy_context_opt(struct mntent *mnt)
Packit 6ef888
{
Packit 6ef888
	char *ctx, *end;
Packit 6ef888
Packit 6ef888
	ctx = hasmntopt(mnt, "context");
Packit 6ef888
	if (ctx == NULL)
Packit 6ef888
		return NULL;
Packit 6ef888
Packit 6ef888
	end = strchr(ctx, ',');
Packit 6ef888
	if (end == NULL)
Packit 6ef888
		return NULL;
Packit 6ef888
Packit 6ef888
	return strndup(ctx, end - ctx);
Packit 6ef888
}