From patchwork Wed Jan 4 21:06:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 134364 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from rcsinet15.oracle.com (rcsinet15.oracle.com [148.87.113.117]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "rcsinet15.oracle.com", Issuer "VeriSign Class 3 International Server CA - G3" (verified OK)) by ozlabs.org (Postfix) with ESMTPS id 8D39F1007D8 for ; Thu, 5 Jan 2012 08:07:31 +1100 (EST) Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by rcsinet15.oracle.com (Switch-3.4.4/Switch-3.4.4) with ESMTP id q04L6tcX032353 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 4 Jan 2012 21:06:55 GMT Received: from oss.oracle.com (oss.oracle.com [141.146.12.120]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q04L6svI024237 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 4 Jan 2012 21:06:54 GMT Received: from localhost ([127.0.0.1] helo=oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1RiY2v-0001h4-Tg; Wed, 04 Jan 2012 13:06:53 -0800 Received: from rcsinet12.oracle.com ([148.87.113.124]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1RiY2t-0001gw-9s for fedfs-utils-devel@oss.oracle.com; Wed, 04 Jan 2012 13:06:51 -0800 Received: from mail-gy0-f171.google.com (mail-gy0-f171.google.com [209.85.160.171]) by rcsinet12.oracle.com (Sentrion-MTA-4.2.0/Sentrion-MTA-4.2.0) with ESMTP id q04L6DpJ008243 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Wed, 4 Jan 2012 21:06:50 GMT Received: by mail-gy0-f171.google.com with SMTP id 10so9357234ghy.2 for ; Wed, 04 Jan 2012 13:06:50 -0800 (PST) Received: by 10.101.9.3 with SMTP id m3mr14776619ani.50.1325711210449; Wed, 04 Jan 2012 13:06:50 -0800 (PST) Received: from degas.1015granger.net (adsl-99-26-161-222.dsl.sfldmi.sbcglobal.net. [99.26.161.222]) by mx.google.com with ESMTPS id 31sm30207706ant.14.2012.01.04.13.06.48 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 04 Jan 2012 13:06:49 -0800 (PST) From: Chuck Lever To: fedfs-utils-devel@oss.oracle.com Date: Wed, 04 Jan 2012 16:06:47 -0500 Message-ID: <20120104210647.8810.43577.stgit@degas.1015granger.net> In-Reply-To: <20120104204207.8810.10569.stgit@degas.1015granger.net> References: <20120104204207.8810.10569.stgit@degas.1015granger.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Flow-Control-Info: class=Default ip=209.85.160.171 ct-class=R6 ct-vol1=0 ct-vol2=0 ct-vol3=0 ct-risk=68 ct-spam1=0 ct-spam2=0 ct-bulk=0 rcpts=1 size=30488 Subject: [fedfs-utils] [PATCH 4/7] libjunction: Factor FedFS-specific code into a separate file X-BeenThere: fedfs-utils-devel@oss.oracle.com X-Mailman-Version: 2.1.9 Precedence: list Reply-To: fedfs-utils Developers List-Id: fedfs-utils Developers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: fedfs-utils-devel-bounces@oss.oracle.com Errors-To: fedfs-utils-devel-bounces@oss.oracle.com X-Source-IP: ucsinet21.oracle.com [156.151.31.93] X-CT-RefId: str=0001.0A090201.4F04BF70.003A:SCFSTAT3865452, ss=1, re=-6.300, fgs=0 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 --- 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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); -}