static int put_alts_slice() { int status; status = wr_altsctr(); if (status) { return (status); } if (ioctl(cur_file, DKIOCADDBAD, NULL) == -1) { (void) fprintf(stderr, "Warning: DKIOCADDBAD ioctl failed\n"); sync(); return (-1); } sync(); return (0); }
int main(int argc, char *argv[]) { extern int optind; extern char *optarg; static char options[] = "Ipa:f:"; char numbuf[100]; char *nxtarg; char *alts_name; minor_t minor_val; struct stat statbuf; struct partition *part = NULL; int alts_slice = -1; int l; int p; int init_flag = 0; int print_flag = 0; int c; int i; FILE *badsecfd = NULL; struct badsec_lst *blc_p; progname = argv[0]; while ( (c=getopt(argc, argv, options)) != EOF ) { switch (c) { case 'I': init_flag = 1; break; case 'p': print_flag = 1; break; case 'a': nxtarg = optarg; for (;*nxtarg != '\0';) add_gbad(strtol(nxtarg, &nxtarg, 0)); break; case 'f': if ((badsecfd = fopen(optarg, "r")) == NULL) { fprintf(stderr, "%s: unable to open %s file\n", progname, optarg); exit(1); } break; default: giveusage(); exit(2); } } /* get the last argument -- device stanza */ if (argc != optind+1) { fprintf(stderr, "Missing disk device name\n"); giveusage(); exit(3); } devname = argv[optind]; if (stat(devname, &statbuf)) { fprintf(stderr, "%s: invalid device %s, stat failed\n", progname, devname); giveusage(); exit(4); } if ((statbuf.st_mode & S_IFMT) != S_IFCHR) { fprintf(stderr, "%s: device %s is not character special\n", progname, devname); giveusage(); exit(5); } minor_val = minor(statbuf.st_rdev); /* * NEED A DEFINE FOR THE PHYSICAL BIT (0x10) */ if ((minor_val & 0x10) == 0) { fprintf(stderr, "%s: device %s is not a physical slice\n", progname, devname); giveusage(); exit(6); } if ((minor_val % V_NUMPAR) != 0) { fprintf(stderr, "%s: device %s is not a slice 0 device\n", progname, devname); giveusage(); exit(7); } if ((devfd=open(devname, O_RDWR)) == -1) { fprintf(stderr, "%s: open of %s failed\n", progname ,devname); perror(""); exit(8); } if ((ioctl (devfd, DKIOCGGEOM, &dkg)) == -1) { fprintf(stderr, "%s: unable to get disk geometry.\n", progname); perror(""); exit(9); } if (ioctl(devfd, DKIOCGVTOC, &vtoc) == -1) { fprintf(stderr, "%s: could not get VTOC.\n", progname); giveusage(); exit(14); } if ((vtoc.v_sanity != VTOC_SANE) || (vtoc.v_version != V_VERSION)) { fprintf(stderr, "%s: invalid VTOC found.\n", progname); giveusage(); exit(15); } if (badsecfd) rd_gbad(badsecfd); #ifdef ADDBAD_DEBUG printf("\n main: Total bad sectors found= %d\n", gbadsl_chain_cnt); for (blc_p=gbadsl_chain; blc_p; blc_p=blc_p->bl_nxt) { for (i=0; i<blc_p->bl_cnt; i++) printf(" badsec=%d ", blc_p->bl_sec[i]); } printf("\n"); #endif #ifdef PPP /* * If init_flag is set, run to completion. */ if (gbadsl_chain_cnt == 0 && init_flag == 0) /* * No defects and not initializing */ exit (0); #endif if (gbadsl_chain_cnt != 0) { if (try_hw_remap () == SUCCESS) exit (0); } /* * get ALTS slice */ for (i = 0; i < V_NUMPAR && alts_slice == -1; i++) { if (vtoc.v_part[i].p_tag == V_ALTSCTR) { alts_slice = i; part = &vtoc.v_part[i]; } } if (alts_slice == -1) { fprintf(stderr, "%s: No alternates slice.\n", progname); exit(16); } l = strlen (devname); sprintf (numbuf, "%d", alts_slice); p = strlen (numbuf); alts_name = (char *)malloc (l + p); strcpy (alts_name, devname); alts_name[l - 2] = 's'; strcpy (&alts_name[l - 1], numbuf); alts_name[l + p - 1] = '\0'; if ((alts_fd=open(alts_name, O_RDWR)) == -1) { fprintf(stderr, "%s: open of %s failed\n", progname ,alts_name); perror(""); exit(9); } if (print_flag) { print_altsec (part); exit (0); } updatebadsec(part, init_flag); wr_altsctr(); if (ioctl(devfd, DKIOCADDBAD, NULL) == -1) { fprintf(stderr, "Warning: DKIOCADDBAD io control failed. System must be re-booted\n"); fprintf(stderr, "for alternate sectors to be usable.\n"); exit(17); } sync(); fclose(badsecfd); close (alts_fd); close (devfd); return(0); }