cifsmount: capture std{err,out} of mount.cifs to log
So it's easier to debug a failed boot. While at it avoid closing stdin, since a printf might inject unexpected input into a wrong place (a socket with FD 0). Redirect stdin from /dev/null instead. While at it improved error handling a bit (fork, waitpid can fail) nfsmount: same here Related: #40554
This commit is contained in:
parent
30a09ca772
commit
a8fa5f19bf
35
log.c
35
log.c
@ -87,3 +87,38 @@ void close_log(void)
|
||||
fclose(logfile);
|
||||
}
|
||||
}
|
||||
|
||||
int redirect2log(int fd)
|
||||
{
|
||||
int rc;
|
||||
if (!logfile) {
|
||||
fprintf(stderr, "%s: log file is not open", __func__);
|
||||
return -1;
|
||||
}
|
||||
rc = dup2(fileno(logfile), fd);
|
||||
if (rc < 0) {
|
||||
log_message("%s: dup2 %d: error: %s", __func__, fd, strerror(errno));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int redirect2null(int fd)
|
||||
{
|
||||
int nullfd = -1, newfd = -1;
|
||||
nullfd = open("/dev/null", O_RDONLY);
|
||||
if (nullfd < 0) {
|
||||
log_message("%s: open /dev/null: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
newfd = dup2(nullfd, fd);
|
||||
if (newfd < 0) {
|
||||
log_message("%s: dup2: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
if (nullfd >= 0) {
|
||||
close(nullfd);
|
||||
}
|
||||
return newfd;
|
||||
}
|
||||
|
||||
|
7
log.h
7
log.h
@ -30,5 +30,12 @@ void vlog_message(const char * s, va_list args);
|
||||
void log_perror(char *msg);
|
||||
void open_log(void);
|
||||
void close_log(void);
|
||||
/* @brief Redirect given fd to log
|
||||
*
|
||||
* Useful to capture the output of external utilities
|
||||
*/
|
||||
int redirect2log(int fd);
|
||||
/* @brief Redirect given fd to /dev/null */
|
||||
int redirect2null(int fd);
|
||||
|
||||
#endif
|
||||
|
61
mount.c
61
mount.c
@ -19,6 +19,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
@ -133,13 +134,14 @@ static int nfsmount(char *dev, char *location)
|
||||
{
|
||||
char spec[PATH_MAX + 17], *sep;
|
||||
struct sockaddr_in saddr;
|
||||
int n, pid, status;
|
||||
pid_t pid;
|
||||
int n, status, ret = -1;
|
||||
|
||||
if ((sep = strchr(dev, ':'))) {
|
||||
*sep = '\0';
|
||||
} else {
|
||||
log_message("nfsmount: directory to mount not in host:dir format");
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
saddr.sin_family = AF_INET;
|
||||
@ -147,7 +149,7 @@ static int nfsmount(char *dev, char *location)
|
||||
mygethostbyname(dev, &saddr.sin_addr)) {
|
||||
log_message("nfsmount: can't get address for %s", dev);
|
||||
*sep = ':';
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*sep = ':';
|
||||
@ -156,17 +158,26 @@ static int nfsmount(char *dev, char *location)
|
||||
strncpy(spec + n, sep, sizeof(spec) - n);
|
||||
log_message("nfsmount %s %s", spec, location);
|
||||
|
||||
if (!(pid = fork())) {
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
log_message("%s: error: fork: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
} else if (pid == 0) {
|
||||
char * argv[] = {"/bin/nfsmount", spec, location, NULL};
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
redirect2log(STDOUT_FILENO);
|
||||
redirect2log(STDERR_FILENO);
|
||||
redirect2null(STDIN_FILENO);
|
||||
execve(argv[0], argv, NULL);
|
||||
exit(1);
|
||||
} else {
|
||||
if (waitpid(pid, &status, 0) < 0) {
|
||||
log_message("%s: error: waitpid: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
return (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1;
|
||||
ret = (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CIFS
|
||||
@ -174,7 +185,8 @@ static int cifsmount(char *dev, char *location)
|
||||
{
|
||||
char spec[PATH_MAX + 19], *sep, *ptr = dev;
|
||||
struct sockaddr_in saddr;
|
||||
int n, pid, status;
|
||||
pid_t pid;
|
||||
int n, status, ret = -1;
|
||||
|
||||
while (*ptr == '/') ptr++;
|
||||
|
||||
@ -182,7 +194,7 @@ static int cifsmount(char *dev, char *location)
|
||||
*sep = '\0';
|
||||
} else {
|
||||
log_message("cifsmount: directory to mount not in //host/dir format");
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
saddr.sin_family = AF_INET;
|
||||
@ -190,7 +202,7 @@ static int cifsmount(char *dev, char *location)
|
||||
mygethostbyname(ptr, &saddr.sin_addr)) {
|
||||
log_message("cifsmount: can't get address for %s", ptr);
|
||||
*sep = '/';
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*sep = '/';
|
||||
@ -201,17 +213,26 @@ static int cifsmount(char *dev, char *location)
|
||||
strncpy(spec + n, sep, sizeof(spec) - n);
|
||||
log_message("cifsmount %s %s", spec, location);
|
||||
|
||||
if (!(pid = fork())) {
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
log_message("%s: error: fork: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
} else if (pid == 0) {
|
||||
char * argv[] = {"/sbin/mount.cifs", spec, location, "-oguest", NULL};
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
redirect2log(STDOUT_FILENO);
|
||||
redirect2log(STDERR_FILENO);
|
||||
redirect2null(STDIN_FILENO);
|
||||
execve(argv[0], argv, NULL);
|
||||
exit(1);
|
||||
} else {
|
||||
if (waitpid(pid, &status, 0) < 0) {
|
||||
log_message("%s: error: waitpid: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
return (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1;
|
||||
ret = (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user