diff options
Diffstat (limited to 'usr/src/lib/librename')
-rw-r--r-- | usr/src/lib/librename/Makefile | 44 | ||||
-rw-r--r-- | usr/src/lib/librename/Makefile.com | 34 | ||||
-rw-r--r-- | usr/src/lib/librename/amd64/Makefile | 19 | ||||
-rw-r--r-- | usr/src/lib/librename/common/librename.c | 229 | ||||
-rw-r--r-- | usr/src/lib/librename/common/librename.h | 43 | ||||
-rw-r--r-- | usr/src/lib/librename/common/llib-lrename | 19 | ||||
-rw-r--r-- | usr/src/lib/librename/common/mapfile-vers | 41 | ||||
-rw-r--r-- | usr/src/lib/librename/i386/Makefile | 18 | ||||
-rw-r--r-- | usr/src/lib/librename/sparc/Makefile | 18 | ||||
-rw-r--r-- | usr/src/lib/librename/sparcv9/Makefile | 19 |
10 files changed, 484 insertions, 0 deletions
diff --git a/usr/src/lib/librename/Makefile b/usr/src/lib/librename/Makefile new file mode 100644 index 0000000000..222523d9a1 --- /dev/null +++ b/usr/src/lib/librename/Makefile @@ -0,0 +1,44 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +include ../Makefile.lib + +HDRS = librename.h +HDRDIR = common +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber lint: $(SUBDIRS) + +install: $(SUBDIRS) $(VARPD_MAPFILES) install_h + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/librename/Makefile.com b/usr/src/lib/librename/Makefile.com new file mode 100644 index 0000000000..f0a22f25ac --- /dev/null +++ b/usr/src/lib/librename/Makefile.com @@ -0,0 +1,34 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +LIBRARY = librename.a +VERS = .1 +OBJECTS = librename.o \ + +include ../../Makefile.lib + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc +CPPFLAGS += -I../common + +SRCDIR = ../common + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../Makefile.targ diff --git a/usr/src/lib/librename/amd64/Makefile b/usr/src/lib/librename/amd64/Makefile new file mode 100644 index 0000000000..15d904c616 --- /dev/null +++ b/usr/src/lib/librename/amd64/Makefile @@ -0,0 +1,19 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/librename/common/librename.c b/usr/src/lib/librename/common/librename.c new file mode 100644 index 0000000000..1e198a50a3 --- /dev/null +++ b/usr/src/lib/librename/common/librename.c @@ -0,0 +1,229 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Implementation of librename(3RENAME) interfaces. + */ + +#include <librename.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <synch.h> + +typedef enum librename_atomic_state { + LIBRENAME_ATOMIC_INITIAL = 0x0, + LIBRENAME_ATOMIC_FSYNC, + LIBRENAME_ATOMIC_RENAME, + LIBRENAME_ATOMIC_POSTSYNC, + LIBRENAME_ATOMIC_COMPLETED +} librename_atomic_state_t; + +struct librename_atomic { + char *lra_fname; /* RO */ + char *lra_altname; /* RO */ + int lra_dirfd; /* RO */ + int lra_tmpfd; /* RO */ + mutex_t lra_lock; + librename_atomic_state_t lra_state; /* lra_lock */ +}; + +int +librename_atomic_fdinit(int fd, const char *file, const char *prefix, + int mode, int flags, librename_atomic_t **outp) +{ + int ret; + int oflags; + librename_atomic_t *lrap; + struct stat st; + + if (fd < 0 || file == NULL || outp == NULL) + return (EINVAL); + + if (flags & ~(LIBRENAME_ATOMIC_NOUNLINK | LIBRENAME_ATOMIC_CLOEXEC)) + return (EINVAL); + + if (strchr(file, '/') != NULL) + return (EINVAL); + + if (prefix != NULL && strchr(prefix, '/') != NULL) + return (EINVAL); + + *outp = NULL; + lrap = malloc(sizeof (librename_atomic_t)); + if (lrap == NULL) + return (errno); + + if (fstat(fd, &st) != 0) { + ret = errno; + free(lrap); + return (ret); + } + + if (!S_ISDIR(st.st_mode)) { + free(lrap); + return (ENOTDIR); + } + + if ((lrap->lra_dirfd = dup(fd)) == -1) { + ret = errno; + free(lrap); + return (ret); + } + + + lrap->lra_fname = strdup(file); + if (lrap->lra_fname == NULL) { + ret = errno; + if (close(lrap->lra_dirfd) != 0) + abort(); + free(lrap); + return (ret); + } + + if (prefix == NULL) { + ret = asprintf(&lrap->lra_altname, ".%d.%s", (int)getpid(), + file); + } else { + ret = asprintf(&lrap->lra_altname, "%s%s", prefix, file); + } + if (ret == -1) { + ret = errno; + free(lrap->lra_fname); + if (close(lrap->lra_dirfd) != 0) + abort(); + free(lrap); + return (errno); + } + + oflags = O_CREAT | O_TRUNC | O_RDWR | O_NOFOLLOW; + if (flags & LIBRENAME_ATOMIC_NOUNLINK) + oflags |= O_EXCL; + + if (flags & LIBRENAME_ATOMIC_CLOEXEC) + oflags |= O_CLOEXEC; + + lrap->lra_tmpfd = openat(lrap->lra_dirfd, lrap->lra_altname, + oflags, mode); + if (lrap->lra_tmpfd < 0) { + ret = errno; + free(lrap->lra_altname); + free(lrap->lra_fname); + if (close(lrap->lra_dirfd) != 0) + abort(); + free(lrap); + return (ret); + } + + if (mutex_init(&lrap->lra_lock, USYNC_THREAD, NULL) != 0) + abort(); + + lrap->lra_state = LIBRENAME_ATOMIC_INITIAL; + *outp = lrap; + return (0); +} + +int +librename_atomic_init(const char *dir, const char *file, const char *prefix, + int mode, int flags, librename_atomic_t **outp) +{ + int fd, ret; + + if ((fd = open(dir, O_RDONLY)) < 0) + return (errno); + + ret = librename_atomic_fdinit(fd, file, prefix, mode, flags, outp); + if (close(fd) != 0) + abort(); + + return (ret); +} + +int +librename_atomic_fd(librename_atomic_t *lrap) +{ + return (lrap->lra_tmpfd); +} + +/* + * To atomically commit a file, we need to go through and do the following: + * + * o fsync the source + * o run rename + * o fsync the source again and the directory. + */ +int +librename_atomic_commit(librename_atomic_t *lrap) +{ + int ret = 0; + + if (mutex_lock(&lrap->lra_lock) != 0) + abort(); + if (lrap->lra_state == LIBRENAME_ATOMIC_COMPLETED) { + ret = EINVAL; + goto out; + } + + if (fsync(lrap->lra_tmpfd) != 0) { + ret = errno; + goto out; + } + lrap->lra_state = LIBRENAME_ATOMIC_FSYNC; + + if (renameat(lrap->lra_dirfd, lrap->lra_altname, lrap->lra_dirfd, + lrap->lra_fname) != 0) { + ret = errno; + goto out; + } + lrap->lra_state = LIBRENAME_ATOMIC_RENAME; + + if (fsync(lrap->lra_tmpfd) != 0) { + ret = errno; + goto out; + } + lrap->lra_state = LIBRENAME_ATOMIC_POSTSYNC; + + if (fsync(lrap->lra_dirfd) != 0) { + ret = errno; + goto out; + } + lrap->lra_state = LIBRENAME_ATOMIC_COMPLETED; + +out: + if (mutex_unlock(&lrap->lra_lock) != 0) + abort(); + return (ret); +} + +void +librename_atomic_fini(librename_atomic_t *lrap) +{ + + free(lrap->lra_altname); + free(lrap->lra_fname); + if (close(lrap->lra_tmpfd) != 0) + abort(); + if (close(lrap->lra_dirfd) != 0) + abort(); + if (mutex_destroy(&lrap->lra_lock) != 0) + abort(); + free(lrap); +} diff --git a/usr/src/lib/librename/common/librename.h b/usr/src/lib/librename/common/librename.h new file mode 100644 index 0000000000..cb344f534c --- /dev/null +++ b/usr/src/lib/librename/common/librename.h @@ -0,0 +1,43 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +#ifndef _LIBRENAME_H +#define _LIBRENAME_H + +/* + * librename(3RENAME) public interfaces + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct librename_atomic librename_atomic_t; + +#define LIBRENAME_ATOMIC_NOUNLINK 0x01 +#define LIBRENAME_ATOMIC_CLOEXEC 0x02 +extern int librename_atomic_init(const char *, const char *, const char *, + int, int, librename_atomic_t **); +extern int librename_atomic_fdinit(int, const char *, const char *, int, int, + librename_atomic_t **); +extern int librename_atomic_fd(librename_atomic_t *); +extern int librename_atomic_commit(librename_atomic_t *); +extern void librename_atomic_fini(librename_atomic_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBRENAME_H */ diff --git a/usr/src/lib/librename/common/llib-lrename b/usr/src/lib/librename/common/llib-lrename new file mode 100644 index 0000000000..6f1dd81a7b --- /dev/null +++ b/usr/src/lib/librename/common/llib-lrename @@ -0,0 +1,19 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <librename.h> diff --git a/usr/src/lib/librename/common/mapfile-vers b/usr/src/lib/librename/common/mapfile-vers new file mode 100644 index 0000000000..af98188b42 --- /dev/null +++ b/usr/src/lib/librename/common/mapfile-vers @@ -0,0 +1,41 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +$mapfile_version 2 + +SYMBOL_VERSION ILLUMOSprivate { + global: + librename_atomic_commit; + librename_atomic_fd; + librename_atomic_fdinit; + librename_atomic_fini; + librename_atomic_init; + local: + *; +}; diff --git a/usr/src/lib/librename/i386/Makefile b/usr/src/lib/librename/i386/Makefile new file mode 100644 index 0000000000..41e699e8f8 --- /dev/null +++ b/usr/src/lib/librename/i386/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/librename/sparc/Makefile b/usr/src/lib/librename/sparc/Makefile new file mode 100644 index 0000000000..41e699e8f8 --- /dev/null +++ b/usr/src/lib/librename/sparc/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/librename/sparcv9/Makefile b/usr/src/lib/librename/sparcv9/Makefile new file mode 100644 index 0000000000..15d904c616 --- /dev/null +++ b/usr/src/lib/librename/sparcv9/Makefile @@ -0,0 +1,19 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) |