Attempt gctl verb "write MBR" when updating.
This should solve the problem of modifying a busy MBR.
This commit is contained in:
parent
1c3cf26412
commit
de78c288db
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=148035
@ -7,6 +7,9 @@ MAN= fdisk.8
|
|||||||
|
|
||||||
.PATH: ${.CURDIR}/../../sys/geom
|
.PATH: ${.CURDIR}/../../sys/geom
|
||||||
|
|
||||||
|
DPADD += ${LIBGEOM}
|
||||||
|
LDADD += -lgeom
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
|
||||||
test: ${PROG}
|
test: ${PROG}
|
||||||
|
@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <libgeom.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -80,7 +81,7 @@ struct mboot {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct mboot mboot;
|
static struct mboot mboot;
|
||||||
static int fd, fdw;
|
static int fd;
|
||||||
|
|
||||||
#define ACTIVE 0x80
|
#define ACTIVE 0x80
|
||||||
|
|
||||||
@ -226,7 +227,7 @@ static char *get_rootdisk(void);
|
|||||||
static void dos(struct dos_partition *partp);
|
static void dos(struct dos_partition *partp);
|
||||||
static int open_disk(int flag);
|
static int open_disk(int flag);
|
||||||
static ssize_t read_disk(off_t sector, void *buf);
|
static ssize_t read_disk(off_t sector, void *buf);
|
||||||
static ssize_t write_disk(off_t sector, void *buf);
|
static int write_disk(off_t sector, void *buf);
|
||||||
static int get_params(void);
|
static int get_params(void);
|
||||||
static int read_s0(void);
|
static int read_s0(void);
|
||||||
static int write_s0(void);
|
static int write_s0(void);
|
||||||
@ -692,10 +693,8 @@ static int
|
|||||||
open_disk(int flag)
|
open_disk(int flag)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int rwmode, p;
|
int rwmode;
|
||||||
char *s;
|
|
||||||
|
|
||||||
fdw = -1;
|
|
||||||
if (stat(disk, &st) == -1) {
|
if (stat(disk, &st) == -1) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
return -2;
|
return -2;
|
||||||
@ -706,23 +705,10 @@ open_disk(int flag)
|
|||||||
warnx("device %s is not character special", disk);
|
warnx("device %s is not character special", disk);
|
||||||
rwmode = a_flag || I_flag || B_flag || flag ? O_RDWR : O_RDONLY;
|
rwmode = a_flag || I_flag || B_flag || flag ? O_RDWR : O_RDONLY;
|
||||||
fd = open(disk, rwmode);
|
fd = open(disk, rwmode);
|
||||||
|
if (fd == -1 && errno == EPERM && rwmode == O_RDWR)
|
||||||
|
fd = open(disk, O_RDONLY);
|
||||||
if (fd == -1 && errno == ENXIO)
|
if (fd == -1 && errno == ENXIO)
|
||||||
return -2;
|
return -2;
|
||||||
if (fd == -1 && errno == EPERM && rwmode == O_RDWR) {
|
|
||||||
fd = open(disk, O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
return -3;
|
|
||||||
for (p = 0; p < NDOSPART; p++) {
|
|
||||||
asprintf(&s, "%ss%d", disk, p + 1);
|
|
||||||
fdw = open(s, rwmode);
|
|
||||||
free(s);
|
|
||||||
if (fdw == -1)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (fdw == -1)
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
warnx("can't open device %s", disk);
|
warnx("can't open device %s", disk);
|
||||||
return -1;
|
return -1;
|
||||||
@ -755,17 +741,46 @@ read_disk(off_t sector, void *buf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static int
|
||||||
write_disk(off_t sector, void *buf)
|
write_disk(off_t sector, void *buf)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
struct gctl_req *grq;
|
||||||
|
const char *q;
|
||||||
|
char fbuf[BUFSIZ];
|
||||||
|
int i, fdw;
|
||||||
|
|
||||||
if (fdw != -1) {
|
grq = gctl_get_handle();
|
||||||
return ioctl(fdw, DIOCSMBR, buf);
|
gctl_ro_param(grq, "verb", -1, "write MBR");
|
||||||
} else {
|
gctl_ro_param(grq, "class", -1, "MBR");
|
||||||
lseek(fd, (sector * 512), 0);
|
q = strrchr(disk, '/');
|
||||||
/* write out in the size that the read_disk found worked */
|
if (q == NULL)
|
||||||
return write(fd, buf, secsize);
|
q = disk;
|
||||||
|
else
|
||||||
|
q++;
|
||||||
|
gctl_ro_param(grq, "geom", -1, q);
|
||||||
|
gctl_ro_param(grq, "data", secsize, buf);
|
||||||
|
q = gctl_issue(grq);
|
||||||
|
if (q == NULL)
|
||||||
|
return(0);
|
||||||
|
warnx("%s", q);
|
||||||
|
|
||||||
|
error = pwrite(fd, buf, secsize, (sector * 512));
|
||||||
|
if (error == secsize)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
for (i = 1; i < 5; i++) {
|
||||||
|
sprintf(fbuf, "%ss%d", disk, i);
|
||||||
|
fdw = open(fbuf, O_RDWR, 0);
|
||||||
|
if (fdw < 0)
|
||||||
|
continue;
|
||||||
|
error = ioctl(fdw, DIOCSMBR, buf);
|
||||||
|
close(fdw);
|
||||||
|
if (error == 0)
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
warnx("Failed to write sector zero");
|
||||||
|
return(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user