mirror of
git://sourceware.org/git/lvm2.git
synced 2025-11-30 04:23:48 +03:00
Compare commits
23 Commits
dev-lvmguy
...
v2_02_174
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71dbe0fe26 | ||
|
|
918f0a92da | ||
|
|
901c919d22 | ||
|
|
03efec2712 | ||
|
|
3071837e21 | ||
|
|
09c792c206 | ||
|
|
f847fcd31a | ||
|
|
c8fdc5c087 | ||
|
|
962874bfe2 | ||
|
|
47b7d4a733 | ||
|
|
26d97f179f | ||
|
|
d79d919329 | ||
|
|
da9a8fdedc | ||
|
|
288e10cf8b | ||
|
|
b3b1e788e1 | ||
|
|
5de9444202 | ||
|
|
043ff47b05 | ||
|
|
e71c3ff187 | ||
|
|
46ddd5520c | ||
|
|
539a48a328 | ||
|
|
c1e3f96c97 | ||
|
|
d4ce98de4d | ||
|
|
0e42b31dc3 |
13
README
13
README
@@ -8,10 +8,15 @@ There is no warranty - see COPYING and COPYING.LIB.
|
||||
Tarballs are available from:
|
||||
ftp://sourceware.org/pub/lvm2/
|
||||
ftp://sources.redhat.com/pub/lvm2/
|
||||
https://github.com/lvmteam/lvm2/releases
|
||||
|
||||
The source code is stored in git:
|
||||
https://sourceware.org/git/?p=lvm2.git
|
||||
git clone git://sourceware.org/git/lvm2.git
|
||||
mirrored to:
|
||||
https://github.com/lvmteam/lvm2
|
||||
git clone https://github.com/lvmteam/lvm2.git
|
||||
git clone git@github.com:lvmteam/lvm2.git
|
||||
|
||||
Mailing list for general discussion related to LVM2:
|
||||
linux-lvm@redhat.com
|
||||
@@ -29,6 +34,14 @@ and multipath-tools:
|
||||
dm-devel@redhat.com
|
||||
Subscribe from https://www.redhat.com/mailman/listinfo/dm-devel
|
||||
|
||||
Website:
|
||||
https://sourceware.org/lvm2/
|
||||
|
||||
Report upstream bugs at:
|
||||
https://bugzilla.redhat.com/enter_bug.cgi?product=LVM%20and%20device-mapper
|
||||
or open issues at:
|
||||
https://github.com/lvmteam/lvm2/issues
|
||||
|
||||
The source code repository used until 7th June 2012 is accessible here:
|
||||
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/?cvsroot=lvm2.
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.02.143-git (2017-07-20)
|
||||
1.02.144-git (2017-09-13)
|
||||
|
||||
10
WHATS_NEW
10
WHATS_NEW
@@ -1,5 +1,11 @@
|
||||
Version 2.02.174 -
|
||||
=================================
|
||||
Version 2.02.175 -
|
||||
======================================
|
||||
|
||||
Version 2.02.174 - 13th September 2017
|
||||
======================================
|
||||
Prevent raid1 split with trackchanges in a shared VG.
|
||||
Avoid double unlocking of client & lockspace mutexes in lvmlockd.
|
||||
Fix leaking of file descriptor for non-blocking filebased locking.
|
||||
Fix check for 2nd mda at end of disk fits if using pvcreate --restorefile.
|
||||
Use maximum metadataarea size that fits with pvcreate --restorefile.
|
||||
Always clear cached bootloaderarea when wiping label e.g. in pvcreate.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
Version 1.02.143 -
|
||||
=================================
|
||||
Version 1.02.144 -
|
||||
======================================
|
||||
|
||||
Version 1.02.143 - 13th September 2017
|
||||
======================================
|
||||
Restore umask when creation of node fails.
|
||||
Add --concise to dmsetup create for many devices with tables in one command.
|
||||
Accept minor number without major in library when it knows dm major number.
|
||||
Introduce single-line concise table output format: dmsetup table --concise
|
||||
|
||||
@@ -171,8 +171,10 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
|
||||
/* Check the status of the command and return the error text */
|
||||
if (status) {
|
||||
*retlen = 1 + ((*buf) ? dm_snprintf(*buf, buflen, "%s",
|
||||
strerror(status)) : -1);
|
||||
if (*buf)
|
||||
*retlen = dm_snprintf(*buf, buflen, "%s", strerror(status)) + 1;
|
||||
else
|
||||
*retlen = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -1105,31 +1105,31 @@ static void be_daemon(int timeout)
|
||||
break;
|
||||
|
||||
default: /* Parent */
|
||||
(void) close(devnull);
|
||||
(void) close(child_pipe[1]);
|
||||
wait_for_child(child_pipe[0], timeout);
|
||||
wait_for_child(child_pipe[0], timeout); /* noreturn */
|
||||
}
|
||||
|
||||
/* Detach ourself from the calling environment */
|
||||
if (close(0) || close(1) || close(2)) {
|
||||
perror("Error closing terminal FDs");
|
||||
exit(4);
|
||||
}
|
||||
setsid();
|
||||
|
||||
if (dup2(devnull, 0) < 0 || dup2(devnull, 1) < 0
|
||||
|| dup2(devnull, 2) < 0) {
|
||||
if ((dup2(devnull, STDIN_FILENO) == -1) ||
|
||||
(dup2(devnull, STDOUT_FILENO) == -1) ||
|
||||
(dup2(devnull, STDERR_FILENO) == -1)) {
|
||||
perror("Error setting terminal FDs to /dev/null");
|
||||
log_error("Error setting terminal FDs to /dev/null: %m");
|
||||
exit(5);
|
||||
}
|
||||
|
||||
if ((devnull > STDERR_FILENO) && close(devnull)) {
|
||||
log_sys_error("close", "/dev/null");
|
||||
exit(7);
|
||||
}
|
||||
|
||||
if (chdir("/")) {
|
||||
log_error("Error setting current directory to /: %m");
|
||||
exit(6);
|
||||
}
|
||||
|
||||
setsid();
|
||||
}
|
||||
|
||||
static int verify_message(char *buf, int len)
|
||||
|
||||
@@ -379,7 +379,7 @@ static int setup_dump_socket(void)
|
||||
rv = bind(s, (struct sockaddr *) &dump_addr, dump_addrlen);
|
||||
if (rv < 0) {
|
||||
rv = -errno;
|
||||
if (!close(s))
|
||||
if (close(s))
|
||||
log_error("failed to close dump socket");
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -2652,10 +2652,16 @@ out_act:
|
||||
ls->drop_vg = drop_vg;
|
||||
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||||
global_dlm_lockspace_exists = 0;
|
||||
/* Avoid a name collision of the same lockspace is added again before this thread is cleaned up. */
|
||||
memset(tmp_name, 0, sizeof(tmp_name));
|
||||
snprintf(tmp_name, MAX_NAME, "REM:%s", ls->name);
|
||||
memcpy(ls->name, tmp_name, MAX_NAME);
|
||||
|
||||
/*
|
||||
* Avoid a name collision of the same lockspace is added again before
|
||||
* this thread is cleaned up. We just set ls->name to a "junk" value
|
||||
* for the short period until the struct is freed. We could make it
|
||||
* blank or fill it with garbage, but instead set it to REM:<name>
|
||||
* to make it easier to follow progress of freeing is via log_debug.
|
||||
*/
|
||||
dm_strncpy(tmp_name, ls->name, sizeof(tmp_name));
|
||||
snprintf(ls->name, sizeof(ls->name), "REM:%s", tmp_name);
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
|
||||
/* worker_thread will join this thread, and free the ls */
|
||||
@@ -3533,11 +3539,15 @@ static int setup_worker_thread(void)
|
||||
|
||||
static void close_worker_thread(void)
|
||||
{
|
||||
int perrno;
|
||||
|
||||
pthread_mutex_lock(&worker_mutex);
|
||||
worker_stop = 1;
|
||||
pthread_cond_signal(&worker_cond);
|
||||
pthread_mutex_unlock(&worker_mutex);
|
||||
pthread_join(worker_thread, NULL);
|
||||
|
||||
if ((perrno = pthread_join(worker_thread, NULL)))
|
||||
log_error("pthread_join worker_thread error %d", perrno);
|
||||
}
|
||||
|
||||
/* client_mutex is locked */
|
||||
@@ -3666,7 +3676,17 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
if (!gl_lsname_dlm[0])
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
} else {
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
int found_lm = 0;
|
||||
|
||||
if (lm_support_dlm() && lm_is_running_dlm())
|
||||
found_lm++;
|
||||
if (lm_support_sanlock() && lm_is_running_sanlock())
|
||||
found_lm++;
|
||||
|
||||
if (!found_lm)
|
||||
strcat(result_flags, "NO_GL_LS,NO_LM");
|
||||
else
|
||||
strcat(result_flags, "NO_GL_LS");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3763,7 +3783,8 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
if (dump_fd >= 0) {
|
||||
/* To avoid deadlock, send data here after the reply. */
|
||||
send_dump_buf(dump_fd, dump_len);
|
||||
close(dump_fd);
|
||||
if (close(dump_fd))
|
||||
log_error("failed to close dump socket %d", dump_fd);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@@ -3836,8 +3857,9 @@ static int add_lock_action(struct action *act)
|
||||
pthread_mutex_lock(&lockspaces_mutex);
|
||||
if (ls_name[0])
|
||||
ls = find_lockspace_name(ls_name);
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
if (!ls) {
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
|
||||
if (act->op == LD_OP_UPDATE && act->rt == LD_RT_VG) {
|
||||
log_debug("lockspace \"%s\" not found ignored for vg update", ls_name);
|
||||
return -ENOLS;
|
||||
@@ -4754,8 +4776,8 @@ static void *client_thread_main(void *arg_in)
|
||||
} else {
|
||||
pthread_mutex_unlock(&cl->mutex);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&client_mutex);
|
||||
} else
|
||||
pthread_mutex_unlock(&client_mutex);
|
||||
}
|
||||
out:
|
||||
return NULL;
|
||||
@@ -4779,11 +4801,15 @@ static int setup_client_thread(void)
|
||||
|
||||
static void close_client_thread(void)
|
||||
{
|
||||
int perrno;
|
||||
|
||||
pthread_mutex_lock(&client_mutex);
|
||||
client_stop = 1;
|
||||
pthread_cond_signal(&client_cond);
|
||||
pthread_mutex_unlock(&client_mutex);
|
||||
pthread_join(client_thread, NULL);
|
||||
|
||||
if ((perrno = pthread_join(client_thread, NULL)))
|
||||
log_error("pthread_join client_thread error %d", perrno);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
2
lib/cache/lvmetad.c
vendored
2
lib/cache/lvmetad.c
vendored
@@ -1281,7 +1281,7 @@ int lvmetad_vg_update_finish(struct volume_group *vg)
|
||||
if (pvl->pv->dev && !lvmetad_pv_found(vg->cmd, &pvl->pv->id, pvl->pv->dev,
|
||||
vgu->fid ? vgu->fid->fmt : pvl->pv->fmt,
|
||||
pvl->pv->label_sector, NULL, NULL, NULL))
|
||||
return 0;
|
||||
return_0;
|
||||
}
|
||||
|
||||
vg->lvmetad_update_pending = 0;
|
||||
|
||||
@@ -437,7 +437,9 @@ out:
|
||||
baton.info = info;
|
||||
baton.label = *label;
|
||||
|
||||
lvmcache_foreach_mda(info, _update_mda, &baton);
|
||||
if (!lvmcache_foreach_mda(info, _update_mda, &baton))
|
||||
return_0;
|
||||
|
||||
lvmcache_make_valid(info);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -115,6 +115,9 @@ static void _flags_str_to_lockd_flags(const char *flags_str, uint32_t *lockd_fla
|
||||
if (strstr(flags_str, "NO_GL_LS"))
|
||||
*lockd_flags |= LD_RF_NO_GL_LS;
|
||||
|
||||
if (strstr(flags_str, "NO_LM"))
|
||||
*lockd_flags |= LD_RF_NO_LM;
|
||||
|
||||
if (strstr(flags_str, "DUP_GL_LS"))
|
||||
*lockd_flags |= LD_RF_DUP_GL_LS;
|
||||
|
||||
@@ -1362,6 +1365,9 @@ int lockd_gl_create(struct cmd_context *cmd, const char *def_mode, const char *v
|
||||
log_error("Global lock failed: check that VG holding global lock exists and is started.");
|
||||
else
|
||||
log_error("Global lock failed: check that global lockspace is started.");
|
||||
|
||||
if (lockd_flags & LD_RF_NO_LM)
|
||||
log_error("Start a lock manager, lvmlockd did not find one running.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1565,6 +1571,9 @@ int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags)
|
||||
* access to lease storage.
|
||||
*/
|
||||
|
||||
if (result == -ENOLS && (lockd_flags & LD_RF_NO_LM))
|
||||
log_error("Start a lock manager, lvmlockd did not find one running.");
|
||||
|
||||
if (result == -ENOLS ||
|
||||
result == -ESTARTING ||
|
||||
result == -EVGKILLED ||
|
||||
@@ -1583,6 +1592,7 @@ int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags)
|
||||
log_error("Global lock failed: storage failed for sanlock leases");
|
||||
else
|
||||
log_error("Global lock failed: error %d", result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define LD_RF_NO_GL_LS 0x00000002
|
||||
#define LD_RF_WARN_GL_REMOVED 0x00000004
|
||||
#define LD_RF_DUP_GL_LS 0x00000008
|
||||
#define LD_RF_NO_LM 0x00000010
|
||||
|
||||
/* lockd_state flags */
|
||||
#define LDST_EX 0x00000001
|
||||
|
||||
@@ -3426,6 +3426,12 @@ int lv_raid_split_and_track(struct logical_volume *lv,
|
||||
int s;
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
|
||||
if (is_lockd_type(lv->vg->lock_type)) {
|
||||
log_error("Splitting raid image is not allowed with lock_type %s.",
|
||||
lv->vg->lock_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!seg_is_mirrored(seg)) {
|
||||
log_error("Unable to split images from non-mirrored RAID.");
|
||||
return 0;
|
||||
|
||||
@@ -116,17 +116,16 @@ static int _do_flock(const char *file, int *fd, int operation, uint32_t nonblock
|
||||
old_errno = errno;
|
||||
if (!nonblock) {
|
||||
sigint_restore();
|
||||
if (sigint_caught())
|
||||
if (sigint_caught()) {
|
||||
log_error("Giving up waiting for lock.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (r) {
|
||||
errno = old_errno;
|
||||
log_sys_error("flock", file);
|
||||
if (close(*fd))
|
||||
log_sys_debug("close", file);
|
||||
*fd = -1;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!stat(file, &buf1) && !fstat(*fd, &buf2) &&
|
||||
@@ -134,6 +133,10 @@ static int _do_flock(const char *file, int *fd, int operation, uint32_t nonblock
|
||||
return 1;
|
||||
} while (!nonblock);
|
||||
|
||||
if (close(*fd))
|
||||
log_sys_debug("close", file);
|
||||
*fd = -1;
|
||||
|
||||
return_0;
|
||||
}
|
||||
|
||||
|
||||
@@ -898,7 +898,12 @@ static int _translate_time_items(struct dm_report *rh, struct time_info *info,
|
||||
id = ti->prop->id;
|
||||
|
||||
if (_is_time_num(id)) {
|
||||
errno = 0;
|
||||
num = strtol(ti->s, &end, 10);
|
||||
if (errno) {
|
||||
log_error("_translate_time_items: invalid time.");
|
||||
return 0;
|
||||
}
|
||||
switch (id) {
|
||||
case TIME_NUM_MULTIPLIER_NEGATIVE:
|
||||
multiplier = -num;
|
||||
|
||||
@@ -334,6 +334,11 @@ static void _daemonise(daemon_state s)
|
||||
struct timeval tval;
|
||||
sigset_t my_sigset;
|
||||
|
||||
if ((fd = open("/dev/null", O_RDWR)) == -1) {
|
||||
fprintf(stderr, "Unable to open /dev/null.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sigemptyset(&my_sigset);
|
||||
if (sigprocmask(SIG_SETMASK, &my_sigset, NULL) < 0) {
|
||||
fprintf(stderr, "Unable to restore signals.\n");
|
||||
@@ -350,6 +355,7 @@ static void _daemonise(daemon_state s)
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) close(fd);
|
||||
/* Wait for response from child */
|
||||
while (!waitpid(pid, &child_status, WNOHANG) && !_shutdown_requested) {
|
||||
tval.tv_sec = 0;
|
||||
@@ -371,15 +377,30 @@ static void _daemonise(daemon_state s)
|
||||
exit(WEXITSTATUS(child_status));
|
||||
}
|
||||
|
||||
if (chdir("/"))
|
||||
if (chdir("/")) {
|
||||
perror("Cannot chdir to /");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((dup2(fd, STDIN_FILENO) == -1) ||
|
||||
(dup2(fd, STDOUT_FILENO) == -1) ||
|
||||
(dup2(fd, STDERR_FILENO) == -1)) {
|
||||
perror("Error setting terminal FDs to /dev/null");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if ((fd > STDERR_FILENO) && close(fd)) {
|
||||
perror("Failed to close /dev/null descriptor");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
/* Switch to sysconf(_SC_OPEN_MAX) ?? */
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
|
||||
fd = 256; /* just have to guess */
|
||||
else
|
||||
fd = rlim.rlim_cur;
|
||||
|
||||
for (--fd; fd >= 0; fd--) {
|
||||
for (--fd; fd > STDERR_FILENO; fd--) {
|
||||
#ifdef __linux__
|
||||
/* Do not close fds preloaded by systemd! */
|
||||
if (_systemd_activation && fd == SD_FD_SOCKET_SERVER)
|
||||
@@ -388,11 +409,6 @@ static void _daemonise(daemon_state s)
|
||||
(void) close(fd);
|
||||
}
|
||||
|
||||
if ((open("/dev/null", O_RDONLY) < 0) ||
|
||||
(open("/dev/null", O_WRONLY) < 0) ||
|
||||
(open("/dev/null", O_WRONLY) < 0))
|
||||
exit(1);
|
||||
|
||||
setsid();
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ static int _create_control(const char *control, uint32_t major, uint32_t minor)
|
||||
*/
|
||||
ret = _control_exists(control, major, minor);
|
||||
if (ret == -1)
|
||||
return 0; /* Failed to unlink existing incorrect node */
|
||||
return_0; /* Failed to unlink existing incorrect node */
|
||||
if (ret)
|
||||
return 1; /* Already exists and correct */
|
||||
|
||||
@@ -284,7 +284,7 @@ static int _create_control(const char *control, uint32_t major, uint32_t minor)
|
||||
(void) dm_prepare_selinux_context(NULL, 0);
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
return_0;
|
||||
|
||||
log_verbose("Creating device %s (%u, %u)", control, major, minor);
|
||||
|
||||
@@ -293,13 +293,12 @@ static int _create_control(const char *control, uint32_t major, uint32_t minor)
|
||||
if (mknod(control, S_IFCHR | S_IRUSR | S_IWUSR,
|
||||
MKDEV((dev_t)major, (dev_t)minor)) < 0) {
|
||||
log_sys_error("mknod", control);
|
||||
(void) dm_prepare_selinux_context(NULL, 0);
|
||||
return 0;
|
||||
ret = 0;
|
||||
}
|
||||
umask(old_umask);
|
||||
(void) dm_prepare_selinux_context(NULL, 0);
|
||||
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -399,13 +399,13 @@ settings, also display comments about deprecation.
|
||||
.ad l
|
||||
\fB--withgeneralpreamble\fP
|
||||
.br
|
||||
Display general file preamble at start of output.
|
||||
Include general config file preamble.
|
||||
.ad b
|
||||
.HP
|
||||
.ad l
|
||||
\fB--withlocalpreamble\fP
|
||||
.br
|
||||
Display local file preamble at start of output.
|
||||
Include local config file preamble.
|
||||
.ad b
|
||||
.HP
|
||||
.ad l
|
||||
|
||||
@@ -397,7 +397,7 @@ the pmspare LV.
|
||||
|
||||
If thin pool metadata is damaged, it may be repairable.
|
||||
Checking and repairing thin pool metadata is analagous to
|
||||
running fsck on a file system.
|
||||
running fsck/repair on a file system.
|
||||
|
||||
When a thin pool LV is activated, lvm runs the thin_check command
|
||||
to check the correctness of the metadata on the pool metadata LV.
|
||||
@@ -774,7 +774,7 @@ While waiting to be extended, the thin pool will queue writes for up to 60
|
||||
seconds (the default). If data space has not been extended after this
|
||||
time, the queued writes will return an error to the caller, e.g. the file
|
||||
system. This can result in file system corruption for non-journaled file
|
||||
systems that may require fsck. When a thin pool returns errors for writes
|
||||
systems that may require repair. When a thin pool returns errors for writes
|
||||
to a thin LV, any file system is subject to losing unsynced user data.
|
||||
|
||||
The 60 second timeout can be changed or disabled with the dm-thin-pool
|
||||
@@ -789,7 +789,7 @@ deadlocks. (The timeout applies to all thin pools on the system.)
|
||||
|
||||
Writes to thin LVs immediately return an error, and no writes are queued.
|
||||
In the case of a file system, this can result in corruption that may
|
||||
require fsck (the specific consequences depend on the thin LV user.)
|
||||
require fs repair (the specific consequences depend on the thin LV user.)
|
||||
|
||||
.I data percent
|
||||
|
||||
@@ -858,7 +858,7 @@ repair.
|
||||
.br
|
||||
See "Manually manage free metadata space of a thin pool LV".
|
||||
|
||||
4. Check and repair file system with fsck.
|
||||
4. Check and repair file system.
|
||||
|
||||
|
||||
.SS Automatic extend settings
|
||||
|
||||
@@ -6157,7 +6157,7 @@ static struct command _dmsetup_commands[] = {
|
||||
{"create", "<dev_name>\n"
|
||||
"\t [-j|--major <major> -m|--minor <minor>]\n"
|
||||
"\t [-U|--uid <uid>] [-G|--gid <gid>] [-M|--mode <octal_mode>]\n"
|
||||
"\t [-u|uuid <uuid>] [--addnodeonresume|--addnodeoncreate]\n"
|
||||
"\t [-u|--uuid <uuid>] [--addnodeonresume|--addnodeoncreate]\n"
|
||||
"\t [--readahead {[+]<sectors>|auto|none}]\n"
|
||||
"\t [-n|--notable|--table {<table>|<table_file>}]\n"
|
||||
"\tcreate --concise [<concise_device_spec_list>]", 0, 2, 0, 0, _create},
|
||||
@@ -7054,7 +7054,13 @@ static int _process_switches(int *argcp, char ***argvp, const char *dev_dir)
|
||||
if (c == 'M' || ind == MODE_ARG) {
|
||||
_switches[MODE_ARG]++;
|
||||
/* FIXME Accept modes as per chmod */
|
||||
_int_args[MODE_ARG] = (int) strtol(optarg, NULL, 8);
|
||||
errno = 0;
|
||||
_int_args[MODE_ARG] = (int) strtol(optarg, &s, 8);
|
||||
if (errno || !s || *s || !_int_args[MODE_ARG]) {
|
||||
log_error("Invalid argument for --mode: %s. %s",
|
||||
optarg, errno ? strerror(errno) : "");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (ind == DEFERRED_ARG)
|
||||
_switches[DEFERRED_ARG]++;
|
||||
|
||||
Reference in New Issue
Block a user