[fedfs-utils] [PATCH 4/7] libjunction: Factor FedFS-specific code into a separate file

Chuck Lever chuck.lever at oracle.com
Wed Jan 4 13:06:47 PST 2012


In preparation for adding support for other types of junctions, split
the main FedFS-specific junction routines into a separate source file
under src/libjunction/ .

Introduce fresh APIs for local junction management tasks that
encapsulate the activities of managing the junction data and the
junction object's mode bits.

The common junction utilities should no longer be invoked outside of
libjunction.  Instead, upper layers should invoke the type-specific
APIs.  We're headed towards a world where callers like rpc.fedfsd
will not care about the mode bit settings or what extended
attributes are used to represent junctions.

Signed-off-by: Chuck Lever <chuck.lever at oracle.com>
---

 src/libjunction/Makefile.am         |    4 
 src/libjunction/fedfs.c             |  426 +++++++++++++++++++++++++++++++++++
 src/libjunction/junction-internal.h |   44 ++++
 src/libjunction/junction.c          |  417 ++--------------------------------
 4 files changed, 503 insertions(+), 388 deletions(-)
 create mode 100644 src/libjunction/fedfs.c
 create mode 100644 src/libjunction/junction-internal.h

diff --git a/src/libjunction/Makefile.am b/src/libjunction/Makefile.am
index 4c43e66..e2a0a4f 100644
--- a/src/libjunction/Makefile.am
+++ b/src/libjunction/Makefile.am
@@ -23,8 +23,10 @@
 ##	http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 ##
 
+noinst_HEADERS		= junction-internal.h
+
 noinst_LTLIBRARIES	= libjunction.la
-libjunction_la_SOURCES	= export-cache.c junction.c
+libjunction_la_SOURCES	= export-cache.c fedfs.c junction.c
 
 CLEANFILES		= cscope.in.out cscope.out cscope.po.out *~
 DISTCLEANFILES		= Makefile.in
diff --git a/src/libjunction/fedfs.c b/src/libjunction/fedfs.c
new file mode 100644
index 0000000..d7af6cc
--- /dev/null
+++ b/src/libjunction/fedfs.c
@@ -0,0 +1,426 @@
+/**
+ * @file src/libjunction/fedfs.c
+ * @brief Create, delete, and read FedFS junctions on the local file system
+ */
+
+/*
+ * Copyright 2010, 2011 Oracle.  All rights reserved.
+ *
+ * This file is part of fedfs-utils.
+ *
+ * fedfs-utils is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2.0 as
+ * published by the Free Software Foundation.
+ *
+ * fedfs-utils is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2.0 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2.0 along with fedfs-utils.  If not, see:
+ *
+ *	http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <wchar.h>
+#include <memory.h>
+#include <signal.h>
+#include <errno.h>
+#include <dirent.h>
+
+#include <attr/xattr.h>
+
+#include "fedfs.h"
+#include "nsdb.h"
+#include "junction.h"
+#include "junction-internal.h"
+#include "xlog.h"
+
+/**
+ * Magic string planted in the "type" attribute of junctions
+ */
+#define FEDFS_JUNCTION_TYPE		"fedfs"
+
+/**
+ * Name of extended attribute containing junction type
+ */
+#define FEDFS_XATTR_NAME_TYPE		"trusted.junction.type"
+
+/**
+ * Name of extended attribute containing junction's FSN UUID
+ */
+#define FEDFS_XATTR_NAME_FSNUUID	"trusted.junction.fsnuuid"
+
+/**
+ * Name of extended attribute containing hostname of NSDB service
+ */
+#define FEDFS_XATTR_NAME_NSDB		"trusted.junction.nsdbname"
+
+/**
+ * Name of extended attribute containing port of NSDB service
+ */
+#define FEDFS_XATTR_NAME_PORT		"trusted.junction.nsdbport"
+
+
+/**
+ * Remove all FedFS-related xattrs from a directory
+ *
+ * @param pathname NUL-terminated C string containing pathname of a directory
+ * @return a FedFsStatus code
+ *
+ * @note Access to trusted attributes requires CAP_SYS_ADMIN.
+ */
+static FedFsStatus
+fedfs_remove_fsn(const char *pathname)
+{
+	FedFsStatus retval;
+	int fd;
+
+	retval = junction_open_path(pathname, &fd);
+	if (retval != FEDFS_OK)
+		return retval;
+
+	retval = junction_remove_xattr(fd, pathname, FEDFS_XATTR_NAME_TYPE);
+	if (retval != FEDFS_OK)
+		goto out;
+	retval = junction_remove_xattr(fd, pathname, FEDFS_XATTR_NAME_FSNUUID);
+	if (retval != FEDFS_OK)
+		goto out;
+	retval = junction_remove_xattr(fd, pathname, FEDFS_XATTR_NAME_NSDB);
+	if (retval != FEDFS_OK)
+		goto out;
+	retval = junction_remove_xattr(fd, pathname, FEDFS_XATTR_NAME_PORT);
+
+out:
+	(void)close(fd);
+	return retval;
+}
+
+/**
+ * Store FedFS information into a junction
+ *
+ * @param pathname NUL-terminated C string containing pathname of a junction
+ * @param fsn_uuid NUL-terminated C string containing FSN UUID to store
+ * @param host an initialized nsdb_t object
+ * @return a FedFsStatus code
+ *
+ * @note Access to trusted attributes requires CAP_SYS_ADMIN.
+ */
+static FedFsStatus
+fedfs_store_fsn(const char *pathname, const char *fsn_uuid, const nsdb_t host)
+{
+	FedFsStatus retval;
+	char buf[20];
+	int fd, len;
+
+	retval = junction_open_path(pathname, &fd);
+	if (retval != FEDFS_OK)
+		return retval;
+
+	retval = junction_set_xattr(fd, pathname, FEDFS_XATTR_NAME_TYPE,
+			FEDFS_XATTR_NAME_TYPE, sizeof(FEDFS_XATTR_NAME_TYPE));
+	if (retval != FEDFS_OK)
+		goto out;
+
+	retval = junction_set_xattr(fd, pathname, FEDFS_XATTR_NAME_FSNUUID,
+			fsn_uuid, strlen(fsn_uuid) + 1);
+	if (retval != FEDFS_OK)
+		goto out;
+
+	retval = junction_set_xattr(fd, pathname, FEDFS_XATTR_NAME_NSDB,
+			nsdb_hostname(host), nsdb_hostname_len(host) + 1);
+	if (retval != FEDFS_OK)
+		goto out;
+
+	len = snprintf(buf, sizeof(buf), "%u", nsdb_port(host));
+	retval = junction_set_xattr(fd, pathname, FEDFS_XATTR_NAME_PORT, buf, len + 1);
+
+out:
+	(void)close(fd);
+	return retval;
+}
+
+/**
+ * Add FedFS junction information to a pre-existing object
+ *
+ * @param pathname NUL-terminated C string containing pathname of a junction
+ * @param fsn_uuid NUL-terminated C string containing FSN UUID to store
+ * @param host an initialized nsdb_t object
+ * @return a FedFsStatus code
+ *
+ * An error occurs if the object referred to by "pathname" does not
+ * exist or contains existing FedFS junction data.
+ */
+FedFsStatus
+fedfs_add_junction(const char *pathname, const char *fsn_uuid, const nsdb_t host)
+{
+	FedFsStatus retval;
+
+	if (fsn_uuid == NULL || host == NULL)
+		return FEDFS_ERR_INVAL;
+
+	retval = fedfs_is_prejunction(pathname);
+	if (retval != FEDFS_ERR_NOTJUNCT)
+		return retval;
+
+	retval = fedfs_store_fsn(pathname, fsn_uuid, host);
+	if (retval != FEDFS_OK)
+		goto out_err;
+
+	retval = junction_save_mode(pathname);
+	if (retval != FEDFS_OK)
+		goto out_err;
+
+	return retval;
+
+out_err:
+	(void)fedfs_remove_fsn(pathname);
+	return retval;
+}
+
+/**
+ * Remove FedFS junction information from an object
+ *
+ * @param pathname NUL-terminated C string containing pathname of a directory
+ * @return a FedFsStatus code
+ *
+ * An error occurs if the object referred to by "pathname" does not
+ * exist or does not contain FedFS junction data.
+ */
+FedFsStatus
+fedfs_delete_junction(const char *pathname)
+{
+	FedFsStatus retval;
+
+	retval = fedfs_is_junction(pathname);
+	if (retval != FEDFS_OK)
+		return retval;
+
+	retval = junction_restore_mode(pathname);
+	if (retval != FEDFS_OK)
+		return retval;
+
+	return fedfs_remove_fsn(pathname);
+}
+
+/**
+ * Retrieve FSN information from a FedFS junction
+ *
+ * @param pathname NUL-terminated C string containing pathname of a junction
+ * @param fsn_uuid OUT: NUL-terminated C string containing FSN UUID to store
+ * @param host OUT: an initialized nsdb_t object
+ * @return a FedFsStatus code
+ *
+ * Caller must free the string returned in "fsn_uuid" with free(3), and
+ * free the NSDB host returned in "host" with nsdb_free_nsdb().
+ */
+FedFsStatus
+fedfs_get_fsn(const char *pathname, char **fsn_uuid, nsdb_t *host)
+{
+	void *uuid_tmp = NULL;
+	void *nsdbname_tmp = NULL;
+	void *port_tmp = NULL;
+	nsdb_t host_tmp = NULL;
+	unsigned short port;
+	FedFsStatus retval;
+	size_t len;
+	int fd;
+
+	if (fsn_uuid == NULL || host == NULL)
+		return FEDFS_ERR_INVAL;
+
+	retval = junction_open_path(pathname, &fd);
+	if (retval != FEDFS_OK)
+		return retval;
+
+	retval = junction_get_xattr(fd, pathname, FEDFS_XATTR_NAME_FSNUUID,
+							&uuid_tmp, &len);
+	if (retval != FEDFS_OK)
+		goto out_err;
+
+	retval = junction_get_xattr(fd, pathname, FEDFS_XATTR_NAME_NSDB,
+					&nsdbname_tmp, &len);
+	if (retval != FEDFS_OK)
+		goto out_err;
+	retval = junction_get_xattr(fd, pathname, FEDFS_XATTR_NAME_PORT,
+					&port_tmp, &len);
+	if (retval != FEDFS_OK)
+		goto out_err;
+
+	retval = FEDFS_ERR_SVRFAULT;
+	if (!nsdb_parse_port_string(port_tmp, &port))
+		goto out_err;
+
+	retval = FEDFS_ERR_NSDB_PARAMS;
+	if (nsdb_lookup_nsdb(nsdbname_tmp, port, &host_tmp, NULL) != FEDFS_OK)
+		goto out_err;
+
+	*fsn_uuid = uuid_tmp;
+	*host = host_tmp;
+	retval = FEDFS_OK;
+
+out:
+	free(port_tmp);
+	free(nsdbname_tmp);
+	(void)close(fd);
+	return retval;
+
+out_err:
+	nsdb_free_nsdb(host_tmp);
+	free(uuid_tmp);
+	goto out;
+	
+}
+
+/**
+ * Predicate: does "pathname" refer to an object that can become a FedFS junction?
+ *
+ * @param pathname NUL-terminated C string containing pathname of a directory
+ * @return a FedFsStatus code
+ *
+ * Return values:
+ *	FEDFS_ERR_NOTJUNCT:	"pathname" refers to an object that can be
+ *				made into a FedFS junction
+ *	FEDFS_ERR_EXIST:	"pathname" refers to something that is
+ *				already a FedFS junction
+ *	FEDFS_ERR_INVAL:	"pathname" does not exist
+ *	Other:			Some error occurred, "pathname" not
+ *				investigated
+ */
+FedFsStatus
+fedfs_is_prejunction(const char *pathname)
+{
+	FedFsStatus retval;
+	int fd;
+
+	retval = junction_open_path(pathname, &fd);
+	if (retval != FEDFS_OK)
+		return retval;
+
+	retval = junction_is_directory(fd, pathname);
+	if (retval != FEDFS_OK)
+		goto out_close;
+
+	retval = junction_is_sticky_bit_set(fd, pathname);
+	switch (retval) {
+	case FEDFS_ERR_NOTJUNCT:
+		break;
+	case FEDFS_OK:
+		goto out_exist;
+	default:
+		goto out_close;
+	}
+
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_TYPE);
+	switch (retval) {
+	case FEDFS_ERR_NOTJUNCT:
+		break;
+	case FEDFS_OK:
+		goto out_exist;
+	default:
+		goto out_close;
+	}
+
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_FSNUUID);
+	switch (retval) {
+	case FEDFS_ERR_NOTJUNCT:
+		break;
+	case FEDFS_OK:
+		goto out_exist;
+	default:
+		goto out_close;
+	}
+
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_NSDB);
+	switch (retval) {
+	case FEDFS_ERR_NOTJUNCT:
+		break;
+	case FEDFS_OK:
+		goto out_exist;
+	default:
+		goto out_close;
+	}
+	
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_PORT);
+	switch (retval) {
+	case FEDFS_ERR_NOTJUNCT:
+		break;
+	case FEDFS_OK:
+		goto out_exist;
+	default:
+		goto out_close;
+	}
+
+out_close:
+	(void)close(fd);
+	return retval;
+out_exist:
+	retval = FEDFS_ERR_EXIST;
+	goto out_close;
+}
+
+/**
+ * Predicate: does "pathname" refer to a FedFS junction?
+ *
+ * @param pathname NUL-terminated C string containing pathname of a directory
+ * @return a FedFsStatus code
+ *
+ * Returns FEDFS_OK if "pathname" refers to a junction, or
+ * FEDFS_ERR_NOTJUNCT if "pathname" does not refer to a junction, or
+ * FEDFS_ERR_INVAL if "pathname" refers to something that does not exist.
+ * Other errors may trickle up from lower layers.
+ *
+ * Return values:
+ *	FEDFS_OK:		"pathname" refers to a FedFS junction
+ *	FEDFS_ERR_NOTJUNCT:	"pathname" refers to an object that can be
+ *				made into a FedFS junction
+ *	FEDFS_ERR_INVAL:	"pathname" does not exist
+ *	Other:			Some error occurred, "pathname" not
+ *				investigated
+ */
+FedFsStatus
+fedfs_is_junction(const char *pathname)
+{
+	FedFsStatus retval;
+	int fd;
+
+	retval = junction_open_path(pathname, &fd);
+	if (retval != FEDFS_OK)
+		return retval;
+
+	retval = junction_is_directory(fd, pathname);
+	if (retval != FEDFS_OK)
+		goto out_close;
+
+	retval = junction_is_sticky_bit_set(fd, pathname);
+	if (retval != FEDFS_OK)
+		goto out_close;
+
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_TYPE);
+	if (retval != FEDFS_OK)
+		goto out_close;
+
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_FSNUUID);
+	if (retval != FEDFS_OK)
+		goto out_close;
+
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_NSDB);
+	if (retval != FEDFS_OK)
+		goto out_close;
+	
+	retval = junction_is_xattr_present(fd, pathname, FEDFS_XATTR_NAME_PORT);
+
+out_close:
+	(void)close(fd);
+	return retval;
+}
diff --git a/src/libjunction/junction-internal.h b/src/libjunction/junction-internal.h
new file mode 100644
index 0000000..c013275
--- /dev/null
+++ b/src/libjunction/junction-internal.h
@@ -0,0 +1,44 @@
+/*
+ * @file src/libjunction/junction-internal.h
+ * @brief Internal declarations for libjunction.a
+ */
+
+/*
+ * Copyright 2011 Oracle.  All rights reserved.
+ *
+ * This file is part of fedfs-utils.
+ *
+ * fedfs-utils is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2.0 as
+ * published by the Free Software Foundation.
+ *
+ * fedfs-utils is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2.0 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2.0 along with fedfs-utils.  If not, see:
+ *
+ *	http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ */
+
+#ifndef _FEDFS_JUNCTION_INTERNAL_H_
+#define _FEDFS_JUNCTION_INTERNAL_H_
+
+FedFsStatus	 junction_open_path(const char *pathname, int *fd);
+FedFsStatus	 junction_is_directory(int fd, const char *path);
+FedFsStatus	 junction_is_sticky_bit_set(int fd, const char *path);
+FedFsStatus	 junction_set_sticky_bit(int fd, const char *path);
+FedFsStatus	 junction_is_xattr_present(int fd, const char *path,
+				const char *name);
+FedFsStatus	 junction_get_xattr(int fd, const char *path, const char *name,
+				void **contents, size_t *contentlen);
+FedFsStatus	 junction_set_xattr(int fd, const char *path, const char *name,
+			const void *contents, const size_t contentlen);
+FedFsStatus	 junction_remove_xattr(int fd, const char *pathname,
+			const char *name);
+FedFsStatus	 junction_save_mode(const char *pathname);
+FedFsStatus	 junction_restore_mode(const char *pathname);
+
+#endif	/* !_FEDFS_JUNCTION_INTERNAL_H_ */
diff --git a/src/libjunction/junction.c b/src/libjunction/junction.c
index 472f4ef..7bde11a 100644
--- a/src/libjunction/junction.c
+++ b/src/libjunction/junction.c
@@ -1,6 +1,6 @@
 /**
  * @file src/libjunction/junction.c
- * @brief Create, delete, and read fedfs junctions on the local file system
+ * @brief Common utilities for managing junctions on the local file system
  */
 
 /*
@@ -43,37 +43,13 @@
 #include "fedfs.h"
 #include "nsdb.h"
 #include "junction.h"
+#include "junction-internal.h"
 #include "xlog.h"
 
 /**
- * Magic string planted in the "type" attribute of junctions
- */
-#define FEDFSD_JUNCTION_TYPE		"fedfs"
-
-/**
  * Name of extended attribute containing saved mode bits
  */
-#define FEDFSD_XATTR_NAME_MODE		"trusted.junction.mode"
-
-/**
- * Name of extended attribute containing junction type
- */
-#define FEDFSD_XATTR_NAME_TYPE		"trusted.junction.type"
-
-/**
- * Name of extended attribute containing junction's FSN UUID
- */
-#define FEDFSD_XATTR_NAME_FSNUUID	"trusted.junction.fsnuuid"
-
-/**
- * Name of extended attribute containing hostname of NSDB service
- */
-#define FEDFSD_XATTR_NAME_NSDB		"trusted.junction.nsdbname"
-
-/**
- * Name of extended attribute containing port of NSDB service
- */
-#define FEDFSD_XATTR_NAME_PORT		"trusted.junction.nsdbport"
+#define JUNCTION_XATTR_NAME_MODE	"trusted.junction.mode"
 
 
 /**
@@ -83,8 +59,8 @@
  * @param fd OUT: a file descriptor number is filled in
  * @return a FedFsStatus code
  */
-static FedFsStatus
-fedfs_open_path(const char *pathname, int *fd)
+FedFsStatus
+junction_open_path(const char *pathname, int *fd)
 {
 	int tmp;
 
@@ -116,8 +92,8 @@ fedfs_open_path(const char *pathname, int *fd)
  * @param path NUL-terminated C string containing pathname of a directory
  * @return a FedFsStatus code
  */
-static FedFsStatus
-fedfs_is_directory(int fd, const char *path)
+FedFsStatus
+junction_is_directory(int fd, const char *path)
 {
 	struct stat stb;
 
@@ -144,8 +120,8 @@ fedfs_is_directory(int fd, const char *path)
  * @param path NUL-terminated C string containing pathname of a directory
  * @return a FedFsStatus code
  */
-static FedFsStatus
-fedfs_is_sticky_bit_set(int fd, const char *path)
+FedFsStatus
+junction_is_sticky_bit_set(int fd, const char *path)
 {
 	struct stat stb;
 
@@ -178,8 +154,8 @@ fedfs_is_sticky_bit_set(int fd, const char *path)
  * @param path NUL-terminated C string containing pathname of a directory
  * @return a FedFsStatus code
  */
-static FedFsStatus
-fedfs_set_sticky_bit(int fd, const char *path)
+FedFsStatus
+junction_set_sticky_bit(int fd, const char *path)
 {
 	struct stat stb;
 
@@ -212,8 +188,8 @@ fedfs_set_sticky_bit(int fd, const char *path)
  *
  * @note Access to trusted attributes requires CAP_SYS_ADMIN.
  */
-static FedFsStatus
-fedfs_is_xattr_present(int fd, const char *path, const char *name)
+FedFsStatus
+junction_is_xattr_present(int fd, const char *path, const char *name)
 {
 	int rc;
 
@@ -256,8 +232,8 @@ fedfs_is_xattr_present(int fd, const char *path, const char *name)
  *
  * @note Access to trusted attributes requires CAP_SYS_ADMIN.
  */
-static FedFsStatus
-fedfs_get_xattr(int fd, const char *path, const char *name, void **contents,
+FedFsStatus
+junction_get_xattr(int fd, const char *path, const char *name, void **contents,
 		size_t *contentlen)
 {
 	void *xattrbuf = NULL;
@@ -306,8 +282,8 @@ fedfs_get_xattr(int fd, const char *path, const char *name, void **contents,
  *
  * @note Access to trusted attributes requires CAP_SYS_ADMIN.
  */
-static FedFsStatus
-fedfs_set_xattr(int fd, const char *path, const char *name,
+FedFsStatus
+junction_set_xattr(int fd, const char *path, const char *name,
 			const void *contents, const size_t contentlen)
 {
 	/*
@@ -335,8 +311,8 @@ fedfs_set_xattr(int fd, const char *path, const char *name,
  *
  * @note Access to trusted attributes requires CAP_SYS_ADMIN.
  */
-static FedFsStatus
-fedfs_remove_xattr(int fd, const char *pathname, const char *name)
+FedFsStatus
+junction_remove_xattr(int fd, const char *pathname, const char *name)
 {
 	/*
 	 * XXX: Eventually should distinguish among several errors:
@@ -353,285 +329,13 @@ fedfs_remove_xattr(int fd, const char *pathname, const char *name)
 }
 
 /**
- * Remove all FedFS-related xattrs from a directory
- *
- * @param pathname NUL-terminated C string containing pathname of a directory
- * @return a FedFsStatus code
- *
- * @note Access to trusted attributes requires CAP_SYS_ADMIN.
- */
-static FedFsStatus
-fedfs_remove_fsn(const char *pathname)
-{
-	FedFsStatus retval;
-	int fd;
-
-	retval = fedfs_open_path(pathname, &fd);
-	if (retval != FEDFS_OK)
-		return retval;
-
-	retval = fedfs_remove_xattr(fd, pathname, FEDFSD_XATTR_NAME_TYPE);
-	if (retval != FEDFS_OK)
-		goto out;
-	retval = fedfs_remove_xattr(fd, pathname, FEDFSD_XATTR_NAME_FSNUUID);
-	if (retval != FEDFS_OK)
-		goto out;
-	retval = fedfs_remove_xattr(fd, pathname, FEDFSD_XATTR_NAME_NSDB);
-	if (retval != FEDFS_OK)
-		goto out;
-	retval = fedfs_remove_xattr(fd, pathname, FEDFSD_XATTR_NAME_PORT);
-
-out:
-	(void)close(fd);
-	return retval;
-}
-
-/**
- * Store FedFS information into a junction
- *
- * @param pathname NUL-terminated C string containing pathname of a junction
- * @param fsn_uuid NUL-terminated C string containing FSN UUID to store
- * @param host an initialized nsdb_t object
- * @return a FedFsStatus code
- */
-static FedFsStatus
-fedfs_store_fsn(const char *pathname, const char *fsn_uuid, const nsdb_t host)
-{
-	FedFsStatus retval;
-	char buf[20];
-	int fd, len;
-
-	retval = fedfs_open_path(pathname, &fd);
-	if (retval != FEDFS_OK)
-		return retval;
-
-	retval = fedfs_set_xattr(fd, pathname, FEDFSD_XATTR_NAME_TYPE,
-			FEDFSD_XATTR_NAME_TYPE, sizeof(FEDFSD_XATTR_NAME_TYPE));
-	if (retval != FEDFS_OK)
-		goto out;
-
-	retval = fedfs_set_xattr(fd, pathname, FEDFSD_XATTR_NAME_FSNUUID,
-			fsn_uuid, strlen(fsn_uuid) + 1);
-	if (retval != FEDFS_OK)
-		goto out;
-
-	retval = fedfs_set_xattr(fd, pathname, FEDFSD_XATTR_NAME_NSDB,
-			nsdb_hostname(host), nsdb_hostname_len(host) + 1);
-	if (retval != FEDFS_OK)
-		goto out;
-
-	len = snprintf(buf, sizeof(buf), "%u", nsdb_port(host));
-	retval = fedfs_set_xattr(fd, pathname, FEDFSD_XATTR_NAME_PORT, buf, len + 1);
-
-out:
-	(void)close(fd);
-	return retval;
-}
-
-/**
- * Retrieve FSN information from a junction
- *
- * @param pathname NUL-terminated C string containing pathname of a junction
- * @param fsn_uuid OUT: NUL-terminated C string containing FSN UUID to store
- * @param host OUT: an initialized nsdb_t object
- * @return a FedFsStatus code
- */
-FedFsStatus
-fedfs_get_fsn(const char *pathname, char **fsn_uuid, nsdb_t *host)
-{
-	void *uuid_tmp = NULL;
-	void *nsdbname_tmp = NULL;
-	void *port_tmp = NULL;
-	nsdb_t host_tmp = NULL;
-	unsigned short port;
-	FedFsStatus retval;
-	size_t len;
-	int fd;
-
-	if (fsn_uuid == NULL || host == NULL)
-		return FEDFS_ERR_INVAL;
-
-	retval = fedfs_open_path(pathname, &fd);
-	if (retval != FEDFS_OK)
-		return retval;
-
-	retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_FSNUUID,
-							&uuid_tmp, &len);
-	if (retval != FEDFS_OK)
-		goto out_err;
-
-	retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_NSDB,
-					&nsdbname_tmp, &len);
-	if (retval != FEDFS_OK)
-		goto out_err;
-	retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_PORT,
-					&port_tmp, &len);
-	if (retval != FEDFS_OK)
-		goto out_err;
-
-	retval = FEDFS_ERR_SVRFAULT;
-	if (!nsdb_parse_port_string(port_tmp, &port))
-		goto out_err;
-
-	retval = FEDFS_ERR_NSDB_PARAMS;
-	if (nsdb_lookup_nsdb(nsdbname_tmp, port, &host_tmp, NULL) != FEDFS_OK)
-		goto out_err;
-
-	*fsn_uuid = uuid_tmp;
-	*host = host_tmp;
-	retval = FEDFS_OK;
-
-out:
-	free(port_tmp);
-	free(nsdbname_tmp);
-	(void)close(fd);
-	return retval;
-
-out_err:
-	nsdb_free_nsdb(host_tmp);
-	free(uuid_tmp);
-	goto out;
-	
-}
-
-/**
- * Predicate: does "pathname" refer to an object that can become a junction?
- *
- * @param pathname NUL-terminated C string containing pathname of a directory
- * @return true if object referred to by "pathname" can become a junction
- *
- * Returns FEDFS_OK if "pathname" refers to an object we can make into a
- * junction, or FEDFS_ERR_EXIST if "pathname" refers to something that could
- * already be a junction.  Other errors may trickle up from lower layers.
- */
-FedFsStatus
-fedfs_is_prejunction(const char *pathname)
-{
-	FedFsStatus retval;
-	int fd;
-
-	retval = fedfs_open_path(pathname, &fd);
-	if (retval != FEDFS_OK)
-		return retval;
-
-	retval = fedfs_is_directory(fd, pathname);
-	if (retval != FEDFS_OK)
-		goto out_close;
-
-	retval = fedfs_is_sticky_bit_set(fd, pathname);
-	switch (retval) {
-	case FEDFS_ERR_NOTJUNCT:
-		break;
-	case FEDFS_OK:
-		goto out_exist;
-	default:
-		goto out_close;
-	}
-
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_TYPE);
-	switch (retval) {
-	case FEDFS_ERR_NOTJUNCT:
-		break;
-	case FEDFS_OK:
-		goto out_exist;
-	default:
-		goto out_close;
-	}
-
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_FSNUUID);
-	switch (retval) {
-	case FEDFS_ERR_NOTJUNCT:
-		break;
-	case FEDFS_OK:
-		goto out_exist;
-	default:
-		goto out_close;
-	}
-
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_NSDB);
-	switch (retval) {
-	case FEDFS_ERR_NOTJUNCT:
-		break;
-	case FEDFS_OK:
-		goto out_exist;
-	default:
-		goto out_close;
-	}
-	
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_PORT);
-	switch (retval) {
-	case FEDFS_ERR_NOTJUNCT:
-		break;
-	case FEDFS_OK:
-		goto out_exist;
-	default:
-		goto out_close;
-	}
-
-out_close:
-	(void)close(fd);
-	return retval;
-out_exist:
-	retval = FEDFS_ERR_EXIST;
-	goto out_close;
-}
-
-/**
- * Predicate: does "pathname" refer to a junction?
- *
- * @param pathname NUL-terminated C string containing pathname of a directory
- * @return true if object referred to by "pathname" is a junction
- *
- * Returns FEDFS_OK if "pathname" refers to a junction, or
- * FEDFS_ERR_NOTJUNCT if "pathname" does not refer to a junction, or
- * FEDFS_ERR_INVAL if "pathname" refers to something that does not exist.
- * Other errors may trickle up from lower layers.
- */
-FedFsStatus
-fedfs_is_junction(const char *pathname)
-{
-	FedFsStatus retval;
-	int fd;
-
-	retval = fedfs_open_path(pathname, &fd);
-	if (retval != FEDFS_OK)
-		return retval;
-
-	retval = fedfs_is_directory(fd, pathname);
-	if (retval != FEDFS_OK)
-		goto out_close;
-
-	retval = fedfs_is_sticky_bit_set(fd, pathname);
-	if (retval != FEDFS_OK)
-		goto out_close;
-
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_TYPE);
-	if (retval != FEDFS_OK)
-		goto out_close;
-
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_FSNUUID);
-	if (retval != FEDFS_OK)
-		goto out_close;
-
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_NSDB);
-	if (retval != FEDFS_OK)
-		goto out_close;
-	
-	retval = fedfs_is_xattr_present(fd, pathname, FEDFSD_XATTR_NAME_PORT);
-
-out_close:
-	(void)close(fd);
-	return retval;
-}
-
-/**
  * Save the object's mode in an xattr.  Saved mode is human-readable.
  *
  * @param pathname NUL-terminated C string containing pathname of a directory
  * @return a FedFsStatus code
  */
 FedFsStatus
-fedfs_save_mode(const char *pathname)
+junction_save_mode(const char *pathname)
 {
 	FedFsStatus retval;
 	unsigned int mode;
@@ -639,7 +343,7 @@ fedfs_save_mode(const char *pathname)
 	char buf[16];
 	int fd;
 
-	retval = fedfs_open_path(pathname, &fd);
+	retval = junction_open_path(pathname, &fd);
 	if (retval != FEDFS_OK)
 		return retval;
 
@@ -651,15 +355,15 @@ fedfs_save_mode(const char *pathname)
 
 	mode = ALLPERMS & stb.st_mode;
 	(void)snprintf(buf, sizeof(buf), "%o", mode);
-	retval = fedfs_set_xattr(fd, pathname, FEDFSD_XATTR_NAME_MODE,
+	retval = junction_set_xattr(fd, pathname, JUNCTION_XATTR_NAME_MODE,
 				buf, strlen(buf));
 	if (retval != FEDFS_OK)
 		goto out;
 
-	retval = fedfs_set_sticky_bit(fd, pathname);
+	retval = junction_set_sticky_bit(fd, pathname);
 	if (retval != FEDFS_OK) {
-		(void)fedfs_remove_xattr(fd, pathname,
-						FEDFSD_XATTR_NAME_MODE);
+		(void)junction_remove_xattr(fd, pathname,
+						JUNCTION_XATTR_NAME_MODE);
 		goto out;
 	}
 
@@ -669,6 +373,7 @@ fedfs_save_mode(const char *pathname)
 out:
 	(void)close(fd);
 	return retval;
+
 }
 
 /**
@@ -678,7 +383,7 @@ out:
  * @return a FedFsStatus code
  */
 FedFsStatus
-fedfs_restore_mode(const char *pathname)
+junction_restore_mode(const char *pathname)
 {
 	FedFsStatus retval;
 	mode_t mode;
@@ -686,11 +391,12 @@ fedfs_restore_mode(const char *pathname)
 	void *buf;
 	int fd;
 
-	retval = fedfs_open_path(pathname, &fd);
+	retval = junction_open_path(pathname, &fd);
 	if (retval != FEDFS_OK)
 		return retval;
 
-	retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_MODE, &buf, &len);
+	retval = junction_get_xattr(fd, pathname, JUNCTION_XATTR_NAME_MODE,
+					&buf, &len);
 	if (retval != FEDFS_OK)
 		goto out;
 
@@ -716,66 +422,3 @@ out:
 	(void)close(fd);
 	return retval;
 }
-
-/**
- * Add FedFS junction information to a pre-existing object
- *
- * @param pathname NUL-terminated C string containing pathname of a junction
- * @param fsn_uuid NUL-terminated C string containing FSN UUID to store
- * @param host an initialized nsdb_t object
- * @return a FedFsStatus code
- *
- * An error occurs if the object referred to by "pathname" does not
- * exist or contains existing FedFS junction data.
- */
-FedFsStatus
-fedfs_add_junction(const char *pathname, const char *fsn_uuid, const nsdb_t host)
-{
-	FedFsStatus retval;
-
-	if (fsn_uuid == NULL || host == NULL)
-		return FEDFS_ERR_INVAL;
-
-	retval = fedfs_is_prejunction(pathname);
-	if (retval != FEDFS_ERR_NOTJUNCT)
-		return retval;
-
-	retval = fedfs_store_fsn(pathname, fsn_uuid, host);
-	if (retval != FEDFS_OK)
-		goto out_err;
-
-	retval = fedfs_save_mode(pathname);
-	if (retval != FEDFS_OK)
-		goto out_err;
-
-	return retval;
-
-out_err:
-	(void)fedfs_remove_fsn(pathname);
-	return retval;
-}
-
-/**
- * Remove FedFS junction information from an object
- *
- * @param pathname NUL-terminated C string containing pathname of a directory
- * @return a FedFsStatus code
- *
- * An error occurs if the object referred to by "pathname" does not
- * exist or does not contain FedFS junction data.
- */
-FedFsStatus
-fedfs_delete_junction(const char *pathname)
-{
-	FedFsStatus retval;
-
-	retval = fedfs_is_junction(pathname);
-	if (retval != FEDFS_OK)
-		return retval;
-
-	retval = fedfs_restore_mode(pathname);
-	if (retval != FEDFS_OK)
-		return retval;
-
-	return fedfs_remove_fsn(pathname);
-}




More information about the fedfs-utils-devel mailing list