int main(int argc, char **argv) { struct DiskPartition *dp; Inode testcreate; Device devno; int fd, count; char *buff="This is a test string"; InitPartitions("vicetab"); dp = VGetPartition("simpled"); devno = dp->device; testcreate = icreate(devno, 0, 0, 0, 0, 0); printf("icreate returned: %d\n", testcreate); if ( testcreate == 0 ) exit(1); fd = iopen(devno, testcreate, O_RDONLY); printf("iopen returned: %d\n", fd); if ( fd != -1 ) close(fd); else exit(2); count = iwrite(devno, testcreate, 0, 0, buff, strlen(buff)); printf("iwrite returned %d (of %d)\n", count, strlen(buff)); printnames(VGetPartition("/tmp/f"), 0, 1, 64); dp = VGetPartition("/tmp/f"); devno = dp->device; testcreate = icreate(devno, 0, 0, 0, 0, 0); printf("icreate returned: %d\n", testcreate); if ( testcreate == 0 ) exit(1); fd = iopen(devno, testcreate, O_RDONLY); printf("iopen returned: %d\n", fd); if ( fd != -1 ) close(fd); else exit(2); count = iwrite(devno, testcreate, 0, 0, buff, strlen(buff)); printf("iwrite returned %d (of %d)\n", count, strlen(buff)); return 0; }
struct DiskPartition64 * FindCurrentPartition(void) { char partName[1024]; char tmp = '\0'; char *p; struct DiskPartition64 *dp; if (!getcwd(partName, 1023)) { perror("pwd"); exit(1); } p = strchr(&partName[1], '/'); if (p) { tmp = *p; *p = '\0'; } if (!(dp = VGetPartition(partName, 0))) { if (tmp) *p = tmp; printf("%s is not a valid vice partition.\n", partName); exit(1); } return dp; }
/* VAttachPartitions2() looks for and attaches /vicepX partitions * where a special file (VICE_ALWAYSATTACH_FILE) exists. This is * used to attach /vicepX directories which aren't on dedicated * partitions, in the NAMEI fileserver. */ static void VAttachPartitions2(void) { #ifdef AFS_NAMEI_ENV DIR *dirp; struct dirent *de; char pname[32]; int wouldattach; dirp = opendir(OS_DIRSEP); while ((de = readdir(dirp))) { strcpy(pname, OS_DIRSEP); strncat(pname, de->d_name, 20); pname[sizeof(pname) - 1] = '\0'; /* Only keep track of "/vicepx" partitions since automounter * may hose us */ if (VIsAlwaysAttach(pname, &wouldattach)) { VCheckPartition(pname, "", 0); } else { struct afs_stat_st st; if (wouldattach && VGetPartition(pname, 0) == NULL && afs_stat(pname, &st) == 0 && S_ISDIR(st.st_mode)) { /* This is a /vicep* dir, and it has not been attached as a * partition. This probably means that this is a /vicep* dir * that is not a separate partition, so just give a notice so * admins are not confused as to why their /vicep* dirs are not * being attached. * * It is possible that the dir _is_ a separate partition and we * failed to attach it earlier, making this message a bit * confusing. But that should be rare, and an error message * about the failure will already be logged right before this, * so it should be clear enough. */ Log("VAttachPartitions: not attaching %s; either it is not a " "separate partition, or it failed to attach (create the " "file %s/" VICE_ALWAYSATTACH_FILE " to force attachment)\n", pname, pname); } } } closedir(dirp); #endif /* AFS_NAMEI_ENV */ }
static int DoSalvageVolume(struct SalvageQueueNode * node, int slot) { char childLog[AFSDIR_PATH_MAX]; struct DiskPartition64 * partP; /* do not allow further forking inside salvager */ canfork = 0; /* do not attempt to close parent's logFile handle as * another thread may have held the lock on the FILE * structure when fork was called! */ afs_snprintf(childLog, sizeof(childLog), "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH, getpid()); logFile = afs_fopen(childLog, "a"); if (!logFile) { /* still nothing, use stdout */ logFile = stdout; ShowLog = 0; } if (node->command.sop.parent <= 0) { Log("salvageServer: invalid volume id specified; salvage aborted\n"); return 1; } partP = VGetPartition(node->command.sop.partName, 0); if (!partP) { Log("salvageServer: Unknown or unmounted partition %s; salvage aborted\n", node->command.sop.partName); return 1; } /* obtain a shared salvage lock in the child worker, so if the * salvageserver restarts (and we continue), we will still hold a lock and * prevent standalone salvagers from interfering */ ObtainSharedSalvageLock(); /* Salvage individual volume; don't notify fs */ SalvageFileSys1(partP, node->command.sop.parent); fclose(logFile); return 0; }
int main(int argc, char **argv) { struct DiskPartition *dp; Inode testcreate; Device devno; int fd, count, i, rc; char *buff="This is a test string"; InitPartitions("vicetab"); if ( argc != 2 ) { printf("Usage %s dir.\n", argv[1]); exit(1); } dp = VGetPartition(argv[1]); devno = dp->device; rc = dp->ops->ListCodaInodes(dp, "/tmp/inodeinfo", NULL, 0); return rc; }
static int handleit(struct cmd_syndesc *as, void *arock) { struct cmd_item *ti; int err = 0; afs_uint32 volumeId = 0; char *partName = 0; struct DiskPartition64 *partP = NULL; #ifndef AFS_NT40_ENV if (geteuid() != 0) { printf("vol-info must be run as root; sorry\n"); exit(1); } #endif if (as->parms[0].items) online = 1; else online = 0; if (as->parms[1].items) DumpVnodes = 1; else DumpVnodes = 0; if (as->parms[2].items) DumpDate = 1; else DumpDate = 0; if (as->parms[3].items) DumpInodeNumber = 1; else DumpInodeNumber = 0; if (as->parms[4].items) InodeTimes = 1; else InodeTimes = 0; if ((ti = as->parms[5].items)) partName = ti->data; if ((ti = as->parms[6].items)) volumeId = strtoul(ti->data, NULL, 10); if (as->parms[7].items) dheader = 1; else dheader = 0; if (as->parms[8].items) { dsizeOnly = 1; dheader = 1; DumpVnodes = 1; } else dsizeOnly = 0; if (as->parms[9].items) { fixheader = 1; } else fixheader = 0; if (as->parms[10].items) { saveinodes = 1; dheader = 1; DumpVnodes = 1; } else saveinodes = 0; if (as->parms[11].items) { orphaned = 1; DumpVnodes = 1; } else #if defined(AFS_NAMEI_ENV) if (as->parms[12].items) { PrintFileNames = 1; DumpVnodes = 1; } else #endif orphaned = 0; DInit(10); err = VAttachPartitions(); if (err) { printf("%d partitions had errors during attach.\n", err); } if (partName) { partP = VGetPartition(partName, 0); if (!partP) { printf("%s is not an AFS partition name on this server.\n", partName); exit(1); } } if (!volumeId) { if (!partP) { HandleAllPart(); } else { HandlePart(partP); } } else { char name1[128]; if (!partP) { partP = FindCurrentPartition(); if (!partP) { printf("Current partition is not a vice partition.\n"); exit(1); } } (void)afs_snprintf(name1, sizeof name1, VFORMAT, afs_printable_uint32_lu(volumeId)); if (dsizeOnly && !saveinodes) printf ("Volume-Id\t Volsize Auxsize Inodesize AVolsize SizeDiff (VolName)\n"); HandleVolume(partP, name1); } return 0; }
static int handleit(struct cmd_syndesc *as, void *arock) { register struct cmd_item *ti; int err = 0; int volumeId = 0; char *partName = 0; char *fileName = NULL; struct DiskPartition64 *partP = NULL; char name1[128]; char tmpPartName[20]; int fromtime = 0; afs_int32 code; #ifndef AFS_NT40_ENV #if 0 if (geteuid() != 0) { fprintf(stderr, "voldump must be run as root; sorry\n"); exit(1); } #endif #endif if ((ti = as->parms[0].items)) partName = ti->data; if ((ti = as->parms[1].items)) volumeId = atoi(ti->data); if ((ti = as->parms[2].items)) fileName = ti->data; if ((ti = as->parms[3].items)) verbose = 1; if (as->parms[4].items && strcmp(as->parms[4].items->data, "0")) { code = ktime_DateToInt32(as->parms[4].items->data, &fromtime); if (code) { fprintf(STDERR, "failed to parse date '%s' (error=%d))\n", as->parms[4].items->data, code); return code; } } DInit(10); err = VAttachPartitions(); if (err) { fprintf(stderr, "%d partitions had errors during attach.\n", err); } if (partName) { if (strlen(partName) == 1) { if (partName[0] >= 'a' && partName[0] <= 'z') { strcpy(tmpPartName, "/vicepa"); tmpPartName[6] = partName[0]; partP = VGetPartition(tmpPartName, 0); } } else { partP = VGetPartition(partName, 0); } if (!partP) { fprintf(stderr, "%s is not an AFS partition name on this server.\n", partName); exit(1); } } if (!volumeId) { fprintf(stderr, "Must specify volume id!\n"); exit(1); } if (!partP) { fprintf(stderr, "must specify vice partition.\n"); exit(1); } (void)afs_snprintf(name1, sizeof name1, VFORMAT, (unsigned long)volumeId); HandleVolume(partP, name1, fileName, fromtime); return 0; }
static int handleit(struct cmd_syndesc *as, void *arock) { struct CmdLine *cmdline = (struct CmdLine*)arock; struct cmd_item *ti; char pname[100], *temp; afs_int32 seenpart = 0, seenvol = 0; VolumeId vid = 0; ProgramType pt; #ifdef FAST_RESTART afs_int32 seenany = 0; #endif char *filename = NULL; struct logOptions logopts; VolumePackageOptions opts; struct DiskPartition64 *partP; memset(&logopts, 0, sizeof(logopts)); #ifdef AFS_SGI_VNODE_GLUE if (afs_init_kernel_config(-1) < 0) { printf ("Can't determine NUMA configuration, not starting salvager.\n"); exit(1); } #endif #ifdef FAST_RESTART { afs_int32 i; for (i = 0; i < CMD_MAXPARMS; i++) { if (as->parms[i].items) { seenany = 1; break; } } } if (!seenany) { printf ("Exiting immediately without salvage. " "Look into the FileLog to find volumes which really need to be salvaged!\n"); Exit(0); } #endif /* FAST_RESTART */ if ((ti = as->parms[0].items)) { /* -partition */ seenpart = 1; strncpy(pname, ti->data, 100); } if ((ti = as->parms[1].items)) { /* -volumeid */ char *end; unsigned long vid_l; if (!seenpart) { printf ("You must also specify '-partition' option with the '-volumeid' option\n"); exit(-1); } seenvol = 1; vid_l = strtoul(ti->data, &end, 10); if (vid_l >= MAX_AFS_UINT32 || vid_l == ULONG_MAX || *end != '\0') { Log("salvage: invalid volume id specified; salvage aborted\n"); Exit(1); } vid = (VolumeId)vid_l; } if (as->parms[2].items) /* -debug */ debug = 1; if (as->parms[3].items) /* -nowrite */ Testing = 1; if (as->parms[4].items) /* -inodes */ ListInodeOption = 1; if (as->parms[5].items || as->parms[21].items) /* -force, -f */ ForceSalvage = 1; if (as->parms[6].items) /* -oktozap */ OKToZap = 1; if (as->parms[7].items) /* -rootinodes */ ShowRootFiles = 1; if (as->parms[8].items) /* -RebuildDirs */ RebuildDirs = 1; if (as->parms[9].items) /* -ForceReads */ forceR = 1; if ((ti = as->parms[10].items)) { /* -Parallel # */ temp = ti->data; if (strncmp(temp, "all", 3) == 0) { PartsPerDisk = 1; temp += 3; } if (strlen(temp) != 0) { Parallel = atoi(temp); if (Parallel < 1) Parallel = 1; if (Parallel > MAXPARALLEL) { printf("Setting parallel salvages to maximum of %d \n", MAXPARALLEL); Parallel = MAXPARALLEL; } } } if ((ti = as->parms[11].items)) { /* -tmpdir */ DIR *dirp; tmpdir = ti->data; dirp = opendir(tmpdir); if (!dirp) { printf ("Can't open temporary placeholder dir %s; using current partition \n", tmpdir); tmpdir = NULL; } else closedir(dirp); } if ((ti = as->parms[12].items)) /* -showlog */ ShowLog = 1; if ((ti = as->parms[13].items)) { /* -showsuid */ Testing = 1; ShowSuid = 1; Showmode = 1; } if ((ti = as->parms[14].items)) { /* -showmounts */ Testing = 1; Showmode = 1; ShowMounts = 1; } if ((ti = as->parms[15].items)) { /* -orphans */ if (Testing) orphans = ORPH_IGNORE; else if (strcmp(ti->data, "remove") == 0 || strcmp(ti->data, "r") == 0) orphans = ORPH_REMOVE; else if (strcmp(ti->data, "attach") == 0 || strcmp(ti->data, "a") == 0) orphans = ORPH_ATTACH; } if ((ti = as->parms[16].items)) { /* -syslog */ if (ShowLog) { fprintf(stderr, "Invalid options: -syslog and -showlog are exclusive.\n"); Exit(1); } if ((ti = as->parms[18].items)) { /* -datelogs */ fprintf(stderr, "Invalid option: -syslog and -datelogs are exclusive.\n"); Exit(1); } #ifndef HAVE_SYSLOG /* Do not silently ignore. */ fprintf(stderr, "Invalid option: -syslog is not available on this platform.\n"); Exit(1); #else logopts.lopt_dest = logDest_syslog; logopts.lopt_tag = "salvager"; if ((ti = as->parms[17].items)) /* -syslogfacility */ logopts.lopt_facility = atoi(ti->data); else logopts.lopt_facility = LOG_DAEMON; /* default value */ #endif } else { logopts.lopt_dest = logDest_file; if ((ti = as->parms[18].items)) { /* -datelogs */ int code = TimeStampLogFile(&filename); if (code != 0) { fprintf(stderr, "Failed to format log file name for -datelogs; code=%d\n", code); Exit(code); } logopts.lopt_filename = filename; } else { logopts.lopt_filename = AFSDIR_SERVER_SLVGLOG_FILEPATH; } } OpenLog(&logopts); SetupLogSignals(); free(filename); /* Free string created by -datelogs, if one. */ Log("%s\n", cml_version_number); LogCommandLine(cmdline->argc, cmdline->argv, "SALVAGER", SalvageVersion, "STARTING AFS", Log); #ifdef FAST_RESTART if (ti = as->parms[19].items) { /* -DontSalvage */ char *msg = "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!"; Log("%s\n", msg); printf("%s\n", msg); Exit(0); } #endif /* Note: if seenvol we initialize this as a standard volume utility: this has the * implication that the file server may be running; negotations have to be made with * the file server in this case to take the read write volume and associated read-only * volumes off line before salvaging */ #ifdef AFS_NT40_ENV if (seenvol) { if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, AFSDIR_SALVAGER_FILE, 0); Log("Failed to initailize winsock, exiting.\n"); Exit(1); } } #endif if (seenvol) { pt = volumeSalvager; } else { pt = salvager; } VOptDefaults(pt, &opts); if (VInitVolumePackage2(pt, &opts)) { Log("errors encountered initializing volume package; salvage aborted\n"); Exit(1); } /* defer lock until we init volume package */ if (get_salvage_lock) { if (seenvol && AskDAFS()) /* support forceDAFS */ ObtainSharedSalvageLock(); else ObtainSalvageLock(); } /* * Ok to defer this as Exit will clean up and no real work is done * init'ing volume package */ if (seenvol) { char *msg = NULL; #ifdef AFS_DEMAND_ATTACH_FS if (!AskDAFS()) { msg = "The DAFS dasalvager cannot be run with a non-DAFS fileserver. Please use 'salvager'."; } if (!msg && !as->parms[20].items) { msg = "The standalone salvager cannot be run concurrently with a Demand Attach Fileserver. Please use 'salvageserver -client <partition> <volume id>' to manually schedule volume salvages with the salvageserver (new versions of 'bos salvage' automatically do this for you). Or, if you insist on using the standalone salvager, add the -forceDAFS flag to your salvager command line."; } #else if (AskDAFS()) { msg = "The non-DAFS salvager cannot be run with a Demand Attach Fileserver. Please use 'salvageserver -client <partition> <volume id>' to manually schedule volume salvages with the salvageserver (new versions of 'bos salvage' automatically do this for you). Or, if you insist on using the standalone salvager, run dasalvager with the -forceDAFS flag."; } #endif if (msg) { Log("%s\n", msg); printf("%s\n", msg); Exit(1); } } DInit(10); #ifdef AFS_NT40_ENV if (myjob.cj_number != NOT_CHILD) { if (!seenpart) { seenpart = 1; (void)strcpy(pname, myjob.cj_part); } } #endif if (seenpart == 0) { for (partP = DiskPartitionList; partP; partP = partP->next) { SalvageFileSysParallel(partP); } SalvageFileSysParallel(0); } else { partP = VGetPartition(pname, 0); if (!partP) { Log("salvage: Unknown or unmounted partition %s; salvage aborted\n", pname); Exit(1); } if (!seenvol) SalvageFileSys(partP, 0); else { /* Salvage individual volume */ SalvageFileSys(partP, vid); } } return (0); }
/* function called with partition name and volid ID, and which removes all * inodes marked with the specified volume ID. If the volume is a read-only * clone, we'll only remove the header inodes, since they're the only inodes * marked with that volume ID. If you want to reclaim all the data, you should * nuke the read-write volume ID. * * Note also that nuking a read-write volume effectively nukes all RO volumes * cloned from that RW volume ID, too, since everything except for their * indices will be gone. */ int nuke(char *aname, afs_int32 avolid) { /* first process the partition containing this junk */ struct afs_stat_st tstat; struct ilist *ti, *ni, *li=NULL; afs_int32 code; int i, forceSal; char wpath[100]; char *lastDevComp; struct DiskPartition64 *dp; #ifdef AFS_NAMEI_ENV char *path; namei_t ufs_name; #endif /* AFS_NAMEI_ENV */ #ifndef AFS_NAMEI_ENV char devName[64]; #endif /* !AFS_NAMEI_ENV */ IHandle_t *fileH; struct ilist *allInodes = 0; if (avolid == 0) return EINVAL; code = afs_stat(aname, &tstat); if (code || (dp = VGetPartition(aname, 0)) == NULL) { printf("volnuke: partition %s does not exist.\n", aname); if (!code) { code = EINVAL; } return code; } /* get the device name for the partition */ #if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV) lastDevComp = aname; #else #ifdef AFS_NT40_ENV lastDevComp = &aname[strlen(aname) - 1]; *lastDevComp = toupper(*lastDevComp); #else { char *tfile = vol_DevName(tstat.st_dev, wpath); if (!tfile) { printf("volnuke: can't find %s's device.\n", aname); return 1; } strcpy(devName, tfile); /* save this from the static buffer */ } /* aim lastDevComp at the 'foo' of '/dev/foo' */ lastDevComp = strrchr(devName, OS_DIRSEPC); /* either points at slash, or there is no slash; adjust appropriately */ if (lastDevComp) lastDevComp++; else lastDevComp = devName; #endif /* AFS_NT40_ENV */ #endif /* AFS_NAMEI_ENV && !AFS_NT40_ENV */ ObtainWriteLock(&localLock); /* OK, we have the mounted on place, aname, the device name (in devName). * all we need to do to call ListViceInodes is find the inodes for the * volume we're nuking. */ code = ListViceInodes(lastDevComp, aname, INVALID_FD, NukeProc, avolid, &forceSal, 0, wpath, &allInodes); if (code == 0) { /* actually do the idecs now */ for (ti = allInodes; ti; ti = ti->next) { for (i = 0; i < ti->freePtr; i++) { #ifndef AFS_PTHREAD_ENV IOMGR_Poll(); /* keep RPC running */ #endif /* !AFS_PTHREAD_ENV */ /* idec this inode into oblivion */ #ifdef AFS_NAMEI_ENV #ifdef AFS_NT40_ENV IH_INIT(fileH, (int)(*lastDevComp - 'A'), avolid, ti->inode[i]); #else IH_INIT(fileH, (int)volutil_GetPartitionID(aname), avolid, ti->inode[i]); #endif /* AFS_NT40_ENV */ namei_HandleToName(&ufs_name, fileH); path = ufs_name.n_path; IH_RELEASE(fileH); if (OS_UNLINK(path) < 0) { Log("Nuke: Failed to remove %s\n", path); } #else /* AFS_NAMEI_ENV */ IH_INIT(fileH, (int)tstat.st_dev, avolid, ti->inode[i]); { int j; for (j = 0; j < ti->count[i]; j++) { code = IH_DEC(fileH, ti->inode[i], avolid); } } IH_RELEASE(fileH); #endif /* AFS_NAMEI_ENV */ } ni = ti->next; if (li) free(li); li = ti; } if (li) free(li); code = 0; /* we really don't care about it except for debugging */ allInodes = NULL; /* at this point, we should try to remove the volume header file itself. * the volume header file is the file named VNNNNN.vol in the UFS file * system, and is a normal file. As such, it is not stamped with the * volume's ID in its inode, and has to be removed explicitly. */ code = VDestroyVolumeDiskHeader(dp, avolid, 0); } else { /* just free things */ for (ti = allInodes; ti; ti = ni) { ni = ti->next; if (li) free(li); li = ti; } if (li) free(li); allInodes = NULL; } ReleaseWriteLock(&localLock); return code; }