/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
+#include <roken.h>
-#include <rx/xdr.h>
+#include <afs/opr.h>
#include <afs/afsint.h>
-#include <stdio.h>
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#if defined(AFS_SUN5_ENV) || defined(AFS_NT40_ENV)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
+#include <rx/rx_queue.h>
+
+#include <afs/afsutil.h>
-#include <afs/assert.h>
#include "nfs.h"
#include "lwp.h"
#include "lock.h"
#include "partition.h"
#include "viceinode.h"
#include "salvage.h"
+#include "daemon_com.h"
#include "fssync.h"
-
-#ifdef O_LARGEFILE
-#define afs_stat stat64
-#else /* !O_LARGEFILE */
-#define afs_stat stat
-#endif /* !O_LARGEFILE */
-
-/*@printflike@*/ extern void Log(const char *format, ...);
-
+#include "common.h"
struct Lock localLock;
-char *vol_DevName();
#define MAXATONCE 100
/* structure containing neatly packed set of inodes and the # of times we'll have
afs_int32 freePtr; /* first free index in this table */
Inode inode[MAXATONCE]; /* inode # */
afs_int32 count[MAXATONCE]; /* link count */
-} *allInodes = 0;
+};
/* called with a structure specifying info about the inode, and our rock (which
* is the volume ID. Returns true if we should keep this inode, otherwise false.
- * Note that ainfo->u.param[0] is always the volume ID, for any vice inode.
*/
static int
-NukeProc(struct ViceInodeInfo *ainfo, afs_int32 avolid)
+NukeProc(struct ViceInodeInfo *ainfo, VolumeId avolid, void *arock)
{
+ struct ilist **allInodes = (struct ilist **)arock;
struct ilist *ti;
- register afs_int32 i;
+ afs_int32 i;
#ifndef AFS_PTHREAD_ENV
IOMGR_Poll(); /* poll so we don't kill the RPC connection */
#endif /* !AFS_PTHREAD_ENV */
/* check if this is the volume we're looking for */
- if (ainfo->u.param[0] != avolid)
- return 0; /* don't want this one */
+ if (ainfo->u.vnode.vnodeNumber == INODESPECIAL) {
+ /* For special inodes, look at both the volume id and the parent id.
+ * If we were given an RW vol id to nuke, we should delete the special
+ * inodes for all volumes in the VG, since we're deleting all of the
+ * regular inodes, too. If we don't do this, on namei would be
+ * impossible to nuke the special inodes for a non-RW volume. */
+ if (ainfo->u.special.volumeId != avolid && ainfo->u.special.parentId != avolid) {
+ return 0;
+ }
+ } else {
+ if (ainfo->u.vnode.volumeId != avolid) {
+ return 0; /* don't want this one */
+ }
+ }
+
/* record the info */
- if (!allInodes || allInodes->freePtr >= MAXATONCE) {
- ti = (struct ilist *)malloc(sizeof(struct ilist));
- memset(ti, 0, sizeof(*ti));
- ti->next = allInodes;
- allInodes = ti;
+ if (!*allInodes || (*allInodes)->freePtr >= MAXATONCE) {
+ ti = calloc(1, sizeof(struct ilist));
+ ti->next = *allInodes;
+ *allInodes = ti;
} else
- ti = allInodes; /* use the one with space */
+ ti = *allInodes; /* use the one with space */
i = ti->freePtr++; /* find our slot in this mess */
ti->inode[i] = ainfo->inodeNumber;
ti->count[i] = ainfo->linkCount;
* indices will be gone.
*/
int
-nuke(char *aname, afs_int32 avolid)
+nuke(char *aname, VolumeId avolid)
{
/* first process the partition containing this junk */
- struct afs_stat tstat;
- struct ilist *ti, *ni;
- register afs_int32 code;
+ struct afs_stat_st tstat;
+ struct ilist *ti, *ni, *li=NULL;
+ afs_int32 code;
int i, forceSal;
- char devName[64], wpath[100];
+ char wpath[100];
char *lastDevComp;
+ struct DiskPartition64 *dp;
#ifdef AFS_NAMEI_ENV
-#ifdef AFS_NT40_ENV
- char path[MAX_PATH];
-#else
char *path;
+
namei_t ufs_name;
-#endif
#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) {
+ 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 */
strcpy(devName, tfile); /* save this from the static buffer */
}
/* aim lastDevComp at the 'foo' of '/dev/foo' */
- lastDevComp = strrchr(devName, '/');
+ lastDevComp = strrchr(devName, OS_DIRSEPC);
/* either points at slash, or there is no slash; adjust appropriately */
if (lastDevComp)
lastDevComp++;
* all we need to do to call ListViceInodes is find the inodes for the
* volume we're nuking.
*/
-#ifdef AFS_NAMEI_ENV
code =
- ListViceInodes(lastDevComp, aname, NULL, NukeProc, avolid, &forceSal,
- 0, wpath);
-#else
- code =
- ListViceInodes(lastDevComp, aname, "/tmp/vNukeXX", NukeProc, avolid,
- &forceSal, 0, wpath);
- unlink("/tmp/vNukeXX"); /* clean it up now */
-#endif
+ 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) {
#ifdef AFS_NT40_ENV
IH_INIT(fileH, (int)(*lastDevComp - 'A'), avolid,
ti->inode[i]);
- nt_HandleToName(path, fileH);
#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;
-#endif /* AFS_NT40_ENV */
IH_RELEASE(fileH);
- if (unlink(path) < 0) {
+ if (OS_UNLINK(path) < 0) {
Log("Nuke: Failed to remove %s\n", path);
}
#else /* AFS_NAMEI_ENV */
IH_RELEASE(fileH);
#endif /* AFS_NAMEI_ENV */
}
- ni = ti->next;
- free(ti);
+ if (li) free(li);
+ li = ti;
}
- code = 0; /* we really don't care about it except for debugging */
+ if (li) free(li);
+
allInodes = NULL;
/* at this point, we should try to remove the volume header file itself.
* 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.
*/
- /* reuse devName buffer now */
-#ifdef AFS_NT40_ENV
- afs_snprintf(devName, sizeof devName, "%c:\\%s", *lastDevComp,
- VolumeExternalName(avolid));
-#else
- afs_snprintf(devName, sizeof devName, "%s/%s", aname,
- VolumeExternalName(avolid));
-#endif /* AFS_NT40_ENV */
- code = unlink(devName);
- if (code)
- code = errno;
+ code = VDestroyVolumeDiskHeader(dp, avolid, 0);
} else {
/* just free things */
for (ti = allInodes; ti; ti = ni) {
ni = ti->next;
- free(ti);
+ if (li) free(li);
+ li = ti;
}
+ if (li) free(li);
allInodes = NULL;
}
ReleaseWriteLock(&localLock);