static int bsd_write_disklabel(struct fdisk_context *cxt) { off_t offset = 0; struct fdisk_bsd_label *l = self_label(cxt); struct bsd_disklabel *d = self_disklabel(cxt); if (l->dos_part) offset = dos_partition_get_start(l->dos_part) * cxt->sector_size; d->d_checksum = 0; d->d_checksum = bsd_dkcksum(d); /* Update label within boot block. */ memmove(&l->bsdbuffer[BSD_LABELSECTOR * DEFAULT_SECTOR_SIZE + BSD_LABELOFFSET], d, sizeof(*d)); #if defined (__alpha__) && BSD_LABELSECTOR == 0 /* Write the checksum to the end of the first sector. */ alpha_bootblock_checksum(l->bsdbuffer); #endif if (lseek(cxt->dev_fd, offset, SEEK_SET) == -1) { fdisk_warn(cxt, _("seek on %s failed"), cxt->dev_path); return -errno; } if (write_all(cxt->dev_fd, l->bsdbuffer, sizeof(l->bsdbuffer))) { fdisk_warn(cxt, _("cannot write %s"), cxt->dev_path); return -errno; } sync_disks(cxt); fdisk_sinfo(cxt, FDISK_INFO_SUCCESS, _("Disklabel written to %s."), cxt->dev_path); return 0; }
static int xbsd_writelabel(struct partition *p) { struct xbsd_disklabel *d = &xbsd_dlabel; unsigned int sector; #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__) sector = get_start_sect(p) + BSD_LABELSECTOR; #else (void)p; /* silence warning */ sector = BSD_LABELSECTOR; #endif d->d_checksum = 0; d->d_checksum = xbsd_dkcksum(d); /* This is necessary if we want to write the bootstrap later, otherwise we'd write the old disklabel with the bootstrap. */ memmove(&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], d, sizeof(struct xbsd_disklabel)); #if defined(__alpha__) && BSD_LABELSECTOR == 0 alpha_bootblock_checksum(disklabelbuffer); seek_sector(0); xwrite(dev_fd, disklabelbuffer, BSD_BBSIZE); #else seek_sector(sector); lseek(dev_fd, BSD_LABELOFFSET, SEEK_CUR); xwrite(dev_fd, d, sizeof(*d)); #endif sync_disks(); return 1; }
int do_sync (void) { if (sync_disks () == -1) { reply_with_perror ("sync"); return -1; } return 0; }
static int xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d) { int sector; #if !defined (__alpha__) && !defined (__powerpc__) sector = get_start_sect(p) + BSD_LABELSECTOR; #elif defined (__alpha__) || defined (__powerpc__) sector = BSD_LABELSECTOR; #endif d -> d_checksum = 0; d -> d_checksum = xbsd_dkcksum (d); /* This is necessary if we want to write the bootstrap later, otherwise we'd write the old disklabel with the bootstrap. */ bcopy (d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], sizeof (struct xbsd_disklabel)); #if defined (__alpha__) && BSD_LABELSECTOR == 0 alpha_bootblock_checksum (disklabelbuffer); if (ext2_llseek (fd, (ext2_loff_t) 0, SEEK_SET) == -1) fatal (unable_to_seek); if (BSD_BBSIZE != write (fd, disklabelbuffer, BSD_BBSIZE)) fatal (unable_to_write); #else if (ext2_llseek (fd, (ext2_loff_t) sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1) fatal (unable_to_seek); if (sizeof (struct xbsd_disklabel) != write (fd, d, sizeof (struct xbsd_disklabel))) fatal (unable_to_write); #endif sync_disks (); return 1; }
int fdisk_bsd_write_bootstrap(struct fdisk_context *cxt) { struct bsd_disklabel dl, *d = self_disklabel(cxt); struct fdisk_bsd_label *l = self_label(cxt); char *name = d->d_type == BSD_DTYPE_SCSI ? "sd" : "wd"; char buf[BUFSIZ]; char *res, *dp, *p; int rc; sector_t sector; snprintf(buf, sizeof(buf), _("Bootstrap: %1$sboot -> boot%1$s (default %1$s)"), name); rc = fdisk_ask_string(cxt, buf, &res); if (rc) goto done; if (res && *res) name = res; snprintf(buf, sizeof(buf), "%s/%sboot", BSD_LINUX_BOOTDIR, name); rc = bsd_get_bootstrap(cxt, buf, l->bsdbuffer, (int) d->d_secsize); if (rc) goto done; /* We need a backup of the disklabel (might have changed). */ dp = &l->bsdbuffer[BSD_LABELSECTOR * DEFAULT_SECTOR_SIZE]; memmove(&dl, dp, sizeof(struct bsd_disklabel)); /* The disklabel will be overwritten by 0's from bootxx anyway */ memset(dp, 0, sizeof(struct bsd_disklabel)); snprintf(buf, sizeof(buf), "%s/boot%s", BSD_LINUX_BOOTDIR, name); rc = bsd_get_bootstrap(cxt, buf, &l->bsdbuffer[d->d_secsize], (int) d->d_bbsize - d->d_secsize); if (rc) goto done; /* check end of the bootstrap */ for (p = dp; p < dp + sizeof(struct bsd_disklabel); p++) { if (!*p) continue; fdisk_warnx(cxt, _("Bootstrap overlaps with disklabel!")); return -EINVAL; } /* move disklabel back */ memmove(dp, &dl, sizeof(struct bsd_disklabel)); sector = 0; if (l->dos_part) sector = dos_partition_get_start(l->dos_part); #if defined (__alpha__) alpha_bootblock_checksum(l->bsdbuffer); #endif if (lseek(cxt->dev_fd, (off_t) sector * DEFAULT_SECTOR_SIZE, SEEK_SET) == -1) { fdisk_warn(cxt, _("seek on %s failed"), cxt->dev_path); rc = -errno; goto done; } if (write_all(cxt->dev_fd, l->bsdbuffer, BSD_BBSIZE)) { fdisk_warn(cxt, _("cannot write %s"), cxt->dev_path); rc = -errno; goto done; } fdisk_sinfo(cxt, FDISK_INFO_SUCCESS, _("Bootstrap installed on %s."), cxt->dev_path); sync_disks(cxt); rc = 0; done: free(res); return rc; }
/* XXX This function really should be cancellable (for the benefit of * virt-sparsify). However currently the library can only handle * cancellation for FileIn/FileOut operations. */ int do_zero_free_space (const char *dir) { size_t len = strlen (dir); char filename[sysroot_len+len+14]; /* sysroot + dir + "/" + 8.3 + "\0" */ int fd; unsigned skip = 0; struct statvfs statbuf; fsblkcnt_t bfree_initial; /* Choose a randomly named 8.3 file. Because of the random name, * this won't conflict with existing files, and it should be * compatible with any filesystem type inc. FAT. */ snprintf (filename, sysroot_len+len+14, "%s%s/XXXXXXXX.XXX", sysroot, dir); if (random_name (filename) == -1) { reply_with_perror ("random_name"); return -1; } if (verbose) printf ("random filename: %s\n", filename); /* Open file and fill with zeroes until we run out of space. */ fd = open (filename, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0600); if (fd == -1) { reply_with_perror ("open: %s", filename); return -1; } /* To estimate progress in this operation, we're going to track * free blocks in this filesystem down to zero. */ if (fstatvfs (fd, &statbuf) == -1) { reply_with_perror ("fstatvfs"); close (fd); return -1; } bfree_initial = statbuf.f_bfree; for (;;) { if (write (fd, zero_buf, sizeof zero_buf) == -1) { if (errno == ENOSPC) /* expected error */ break; reply_with_perror ("write: %s", filename); close (fd); unlink (filename); return -1; } skip++; if ((skip & 256) == 0 && fstatvfs (fd, &statbuf) == 0) notify_progress (bfree_initial - statbuf.f_bfree, bfree_initial); } /* Make sure the file is completely written to disk. */ close (fd); /* expect this to give an error, don't check it */ sync_disks (); notify_progress (bfree_initial, bfree_initial); /* Remove the file. */ if (unlink (filename) == -1) { reply_with_perror ("unlink: %s", filename); return -1; } return 0; }
static void xbsd_write_bootstrap(void) { char path[MAXPATHLEN]; const char *bootdir = BSD_LINUX_BOOTDIR; const char *dkbasename; struct xbsd_disklabel dl; char *d, *p, *e; int sector; if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI) dkbasename = "sd"; else dkbasename = "wd"; snprintf(path, sizeof(path), "Bootstrap: %sboot -> boot%s (%s): ", dkbasename, dkbasename, dkbasename); if (read_line(path)) { dkbasename = line_ptr; } snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename); if (!xbsd_get_bootstrap(path, disklabelbuffer, (int) xbsd_dlabel.d_secsize)) return; /* We need a backup of the disklabel (xbsd_dlabel might have changed). */ d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE]; memmove(&dl, d, sizeof(struct xbsd_disklabel)); /* The disklabel will be overwritten by 0's from bootxx anyway */ memset(d, 0, sizeof(struct xbsd_disklabel)); snprintf(path, sizeof(path), "%s/boot%s", bootdir, dkbasename); if (!xbsd_get_bootstrap(path, &disklabelbuffer[xbsd_dlabel.d_secsize], (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize)) return; e = d + sizeof(struct xbsd_disklabel); for (p = d; p < e; p++) if (*p) { printf("Bootstrap overlaps with disk label!\n"); exit(EXIT_FAILURE); } memmove(d, &dl, sizeof(struct xbsd_disklabel)); #if defined(__powerpc__) || defined(__hppa__) sector = 0; #elif defined(__alpha__) sector = 0; alpha_bootblock_checksum(disklabelbuffer); #else sector = get_start_sect(xbsd_part); #endif seek_sector(sector); xwrite(dev_fd, disklabelbuffer, BSD_BBSIZE); #if defined(__alpha__) printf("Bootstrap installed on %s\n", disk_device); #else printf("Bootstrap installed on %s\n", partname(disk_device, xbsd_part_index+1, 0)); #endif sync_disks(); }
static void xbsd_write_bootstrap (void) { char *bootdir = BSD_LINUX_BOOTDIR; char path[MAXPATHLEN]; char *dkbasename; struct xbsd_disklabel dl; char *d, *p, *e; int sector; if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI) dkbasename = "sd"; else dkbasename = "wd"; printf (_("Bootstrap: %sboot -> boot%s (%s): "), dkbasename, dkbasename, dkbasename); if (read_line ()) { line_ptr[strlen (line_ptr)-1] = '\0'; dkbasename = line_ptr; } sprintf (path, "%s/%sboot", bootdir, dkbasename); if (!xbsd_get_bootstrap (path, disklabelbuffer, (int) xbsd_dlabel.d_secsize)) return; /* We need a backup of the disklabel (xbsd_dlabel might have changed). */ d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE]; bcopy (d, &dl, sizeof (struct xbsd_disklabel)); /* The disklabel will be overwritten by 0's from bootxx anyway */ bzero (d, sizeof (struct xbsd_disklabel)); sprintf (path, "%s/boot%s", bootdir, dkbasename); if (!xbsd_get_bootstrap (path, &disklabelbuffer[xbsd_dlabel.d_secsize], (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize)) return; e = d + sizeof (struct xbsd_disklabel); for (p=d; p < e; p++) if (*p) { fprintf (stderr, _("Bootstrap overlaps with disk label!\n")); exit ( EXIT_FAILURE ); } bcopy (&dl, d, sizeof (struct xbsd_disklabel)); #if defined (__powerpc__) sector = 0; #elif defined (__alpha__) sector = 0; alpha_bootblock_checksum (disklabelbuffer); #else sector = get_start_sect(xbsd_part); #endif if (ext2_llseek (fd, (ext2_loff_t) sector * SECTOR_SIZE, SEEK_SET) == -1) fatal (unable_to_seek); if (BSD_BBSIZE != write (fd, disklabelbuffer, BSD_BBSIZE)) fatal (unable_to_write); #if defined (__alpha__) printf (_("Bootstrap installed on %s.\n"), disk_device); #else printf (_("Bootstrap installed on %s.\n"), partname (disk_device, xbsd_part_index+1, 0)); #endif sync_disks (); }