]> sourceware.org Git - lvm2.git/blame - libdm/libdm-file.c
Fix error message when pvmove LV activation fails with name already in use.
[lvm2.git] / libdm / libdm-file.c
CommitLineData
f34c169a
AK
1/*
2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
147d5fac 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
f34c169a
AK
4 *
5 * This file is part of the device-mapper userspace tools.
6 *
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
147d5fac 9 * of the GNU Lesser General Public License v.2.1.
f34c169a 10 *
147d5fac 11 * You should have received a copy of the GNU Lesser General Public License
f34c169a
AK
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 */
15
3e5b6ed2 16#include "dmlib.h"
f34c169a
AK
17
18#include <sys/file.h>
19#include <fcntl.h>
20#include <dirent.h>
3d2aecf0 21
f34c169a
AK
22static int _create_dir_recursive(const char *dir)
23{
24 char *orig, *s;
7dc850db 25 int rc, r = 0;
f34c169a
AK
26
27 log_verbose("Creating directory \"%s\"", dir);
28 /* Create parent directories */
5e3bd867 29 orig = s = dm_strdup(dir);
b23975ee
ZK
30 if (!s) {
31 log_error("Failed to duplicate directory name.");
32 return 0;
33 }
34
f34c169a
AK
35 while ((s = strchr(s, '/')) != NULL) {
36 *s = '\0';
37 if (*orig) {
38 rc = mkdir(orig, 0777);
39 if (rc < 0 && errno != EEXIST) {
1c200869
JM
40 if (errno != EROFS)
41 log_sys_error("mkdir", orig);
7dc850db 42 goto out;
f34c169a
AK
43 }
44 }
45 *s++ = '/';
46 }
f34c169a
AK
47
48 /* Create final directory */
49 rc = mkdir(dir, 0777);
50 if (rc < 0 && errno != EEXIST) {
1c200869
JM
51 if (errno != EROFS)
52 log_sys_error("mkdir", orig);
7dc850db 53 goto out;
f34c169a 54 }
7dc850db
AK
55
56 r = 1;
57out:
58 dm_free(orig);
59 return r;
f34c169a
AK
60}
61
3f311f1d 62int dm_create_dir(const char *dir)
f34c169a
AK
63{
64 struct stat info;
65
66 if (!*dir)
67 return 1;
68
69 if (stat(dir, &info) < 0)
70 return _create_dir_recursive(dir);
71
72 if (S_ISDIR(info.st_mode))
73 return 1;
74
75 log_error("Directory \"%s\" not found", dir);
76 return 0;
77}
78
14254bd0
PR
79int dm_is_empty_dir(const char *dir)
80{
81 struct dirent *dirent;
82 DIR *d;
83
84 if (!(d = opendir(dir))) {
85 log_sys_error("opendir", dir);
86 return 0;
87 }
88
89 while ((dirent = readdir(d)))
90 if (strcmp(dirent->d_name, ".") && strcmp(dirent->d_name, ".."))
91 break;
92
93 if (closedir(d))
94 log_sys_error("closedir", dir);
95
96 return dirent ? 0 : 1;
97}
98
0c3cd7e2
JM
99int dm_fclose(FILE *stream)
100{
101 int prev_fail = ferror(stream);
102 int fclose_fail = fclose(stream);
103
104 /* If there was a previous failure, but fclose succeeded,
105 clear errno, since ferror does not set it, and its value
106 may be unrelated to the ferror-reported failure. */
107 if (prev_fail && !fclose_fail)
108 errno = 0;
109
110 return prev_fail || fclose_fail ? EOF : 0;
111}
8c4e8a18
FDN
112
113int dm_create_lockfile(const char *lockfile)
114{
115 int fd, value;
116 size_t bufferlen;
117 ssize_t write_out;
118 struct flock lock;
119 char buffer[50];
d95a85ca 120 int retries = 0;
8c4e8a18
FDN
121
122 if((fd = open(lockfile, O_CREAT | O_WRONLY,
123 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
124 log_error("Cannot open lockfile [%s], error was [%s]",
125 lockfile, strerror(errno));
126 return 0;
127 }
128
129 lock.l_type = F_WRLCK;
130 lock.l_start = 0;
131 lock.l_whence = SEEK_SET;
132 lock.l_len = 0;
4cc5adf4 133retry_fcntl:
8c4e8a18 134 if (fcntl(fd, F_SETLK, &lock) < 0) {
4cc5adf4
AK
135 switch (errno) {
136 case EINTR:
137 goto retry_fcntl;
4cc5adf4
AK
138 case EACCES:
139 case EAGAIN:
d95a85ca
PR
140 if (retries == 20) {
141 log_error("Cannot lock lockfile [%s], error was [%s]",
142 lockfile, strerror(errno));
143 break;
144 } else {
145 ++ retries;
146 usleep(1000);
147 goto retry_fcntl;
148 }
4cc5adf4 149 default:
8c4e8a18 150 log_error("process is already running");
4cc5adf4 151 }
8c4e8a18 152
4cc5adf4 153 goto fail_close;
8c4e8a18
FDN
154 }
155
156 if (ftruncate(fd, 0) < 0) {
157 log_error("Cannot truncate pidfile [%s], error was [%s]",
158 lockfile, strerror(errno));
159
4cc5adf4 160 goto fail_close_unlink;
8c4e8a18
FDN
161 }
162
163 memset(buffer, 0, sizeof(buffer));
164 snprintf(buffer, sizeof(buffer)-1, "%u\n", getpid());
165
166 bufferlen = strlen(buffer);
167 write_out = write(fd, buffer, bufferlen);
168
169 if ((write_out < 0) || (write_out == 0 && errno)) {
170 log_error("Cannot write pid to pidfile [%s], error was [%s]",
171 lockfile, strerror(errno));
172
4cc5adf4 173 goto fail_close_unlink;
8c4e8a18
FDN
174 }
175
a1eba521 176 if ((write_out == 0) || ((size_t)write_out < bufferlen)) {
8c4e8a18
FDN
177 log_error("Cannot write pid to pidfile [%s], shortwrite of"
178 "[%" PRIsize_t "] bytes, expected [%" PRIsize_t "]\n",
179 lockfile, write_out, bufferlen);
180
4cc5adf4 181 goto fail_close_unlink;
8c4e8a18
FDN
182 }
183
184 if ((value = fcntl(fd, F_GETFD, 0)) < 0) {
185 log_error("Cannot get close-on-exec flag from pidfile [%s], "
186 "error was [%s]", lockfile, strerror(errno));
187
4cc5adf4 188 goto fail_close_unlink;
8c4e8a18
FDN
189 }
190 value |= FD_CLOEXEC;
191 if (fcntl(fd, F_SETFD, value) < 0) {
192 log_error("Cannot set close-on-exec flag from pidfile [%s], "
193 "error was [%s]", lockfile, strerror(errno));
194
4cc5adf4 195 goto fail_close_unlink;
8c4e8a18
FDN
196 }
197
198 return 1;
199
4cc5adf4 200fail_close_unlink:
8c4e8a18
FDN
201 if (unlink(lockfile))
202 stack;
4cc5adf4
AK
203fail_close:
204 if (close(fd))
205 stack;
8c4e8a18
FDN
206
207 return 0;
208}
405c4a45
JEB
209
210int dm_daemon_is_running(const char* lockfile)
211{
212 int fd;
213 struct flock lock;
214
215 if((fd = open(lockfile, O_RDONLY)) < 0)
216 return 0;
217
218 lock.l_type = F_WRLCK;
219 lock.l_start = 0;
220 lock.l_whence = SEEK_SET;
221 lock.l_len = 0;
222 if (fcntl(fd, F_GETLK, &lock) < 0) {
223 log_error("Cannot check lock status of lockfile [%s], error was [%s]",
224 lockfile, strerror(errno));
225 if (close(fd))
226 stack;
227 return 0;
228 }
229
230 if (close(fd))
231 stack;
232
233 return (lock.l_type == F_UNLCK) ? 0 : 1;
234}
This page took 0.146262 seconds and 5 git commands to generate.