Beispiel #1
0
/**
 * create and write a volume disk header to disk.
 *
 * @param[in] hdr   volume disk header
 * @param[in] dp    disk partition object
 *
 * @return operation status
 *    @retval 0 success
 *    @retval EEXIST volume header already exists
 *    @retval EIO failed to write volume header
 *
 * @internal
 */
afs_int32
VCreateVolumeDiskHeader(VolumeDiskHeader_t * hdr,
			struct DiskPartition64 * dp)
{
    afs_int32 code = 0;
#ifdef AFS_DEMAND_ATTACH_FS
    SYNC_response res;
#endif /* AFS_DEMAND_ATTACH_FS */

    code = _VWriteVolumeDiskHeader(hdr, dp, O_CREAT | O_EXCL);
    if (code) {
	goto done;
    }

#ifdef AFS_DEMAND_ATTACH_FS
    memset(&res, 0, sizeof(res));
    code = FSYNC_VGCAdd(dp->name, hdr->parent, hdr->id, FSYNC_WHATEVER, &res);
    if (code) {
	Log("VCreateVolumeDiskHeader: FSYNC_VGCAdd(%s, %lu, %lu) failed "
	    "with code %ld reason %ld\n", dp->name,
	    afs_printable_uint32_lu(hdr->parent),
	    afs_printable_uint32_lu(hdr->id),
	    afs_printable_int32_ld(code),
	    afs_printable_int32_ld(res.hdr.reason));
    }
#endif /* AFS_DEMAND_ATTACH_FS */

 done:
    return code;
}
Beispiel #2
0
int
afscp_GetStatus(const struct afscp_venusfid *fid, struct AFSFetchStatus *s)
{
    struct afscp_volume *v;
    struct afscp_server *server;
    struct AFSCallBack cb;
    struct AFSVolSync vs;
    struct AFSFid tf = fid->fid;
    struct afscp_statent *stored, key;
    void *cached;
    int code, i, j;
    time_t now;

    v = afscp_VolumeById(fid->cell, fid->fid.Volume);
    if (v == NULL) {
	return -1;
    }
    memset(&key, 0, sizeof(key));
    memcpy(&key.me, fid, sizeof(*fid));

    cached = tfind(&key, &v->statcache, statcompare);
    if (cached != NULL) {
	stored = *(struct afscp_statent **)cached;
	pthread_mutex_lock(&(stored->mtx));
	memmove(s, &stored->status, sizeof(*s));
	afs_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n",
		     fid->cell->id, fid->fid.Volume, fid->fid.Vnode,
		     fid->fid.Unique));
	if (stored->nwaiters)
	    pthread_cond_broadcast(&(stored->cv));
	pthread_mutex_unlock(&(stored->mtx));
	return 0;
    }

    code = ENOENT;
    for (i = 0; i < v->nservers; i++) {
	server = afscp_ServerByIndex(v->servers[i]);
	if (server && server->naddrs > 0) {
	    for (j = 0; j < server->naddrs; j++) {
		time(&now);
		code = RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs);
		if (code == 0) {
		    afscp_AddCallBack(server, &fid->fid, s, &cb, now);	/* calls _StatStuff */
		    afs_dprintf(("Stat %d.%lu.%lu.%lu"
				 " ok: type %ld size %ld\n",
				 fid->cell->id,
				 afs_printable_uint32_lu(fid->fid.Volume),
				 afs_printable_uint32_lu(fid->fid.Vnode),
				 afs_printable_uint32_lu(fid->fid.Unique),
				 afs_printable_int32_ld(s->FileType),
				 afs_printable_int32_ld(s->Length)));
		    return 0;
		}
	    }
	}
    }
    afscp_errno = code;
    return -1;
}
Beispiel #3
0
static int
ListEntry(void * handle, char *name, afs_int32 vnode, afs_int32 unique)
{
    printf("%s\t%ld\t%ld\n", name, afs_printable_int32_ld(vnode),
	   afs_printable_int32_ld(unique));

    return 0;
}
Beispiel #4
0
/**
 * destroy a volume disk header.
 *
 * @param[in] dp      disk partition object
 * @param[in] volid   volume id
 * @param[in] parent  parent's volume id, 0 if unknown
 *
 * @return operation status
 *    @retval 0 success
 *
 * @note if parent is 0, the parent volume ID will be looked up from the
 * fileserver
 *
 * @note for non-DAFS, parent is currently ignored
 */
afs_int32
VDestroyVolumeDiskHeader(struct DiskPartition64 * dp,
			 VolumeId volid,
			 VolumeId parent)
{
    afs_int32 code = 0;
    char path[MAXPATHLEN];
#ifdef AFS_DEMAND_ATTACH_FS
    SYNC_response res;
#endif /* AFS_DEMAND_ATTACH_FS */

    (void)afs_snprintf(path, sizeof(path),
                       "%s/" VFORMAT,
                       VPartitionPath(dp), afs_printable_uint32_lu(volid));
    code = unlink(path);
    if (code) {
	Log("VDestroyVolumeDiskHeader: Couldn't unlink disk header, error = %d\n", errno);
	goto done;
    }

#ifdef AFS_DEMAND_ATTACH_FS
    memset(&res, 0, sizeof(res));
    if (!parent) {
	FSSYNC_VGQry_response_t q_res;

	code = FSYNC_VGCQuery(dp->name, volid, &q_res, &res);
	if (code) {
	    Log("VDestroyVolumeDiskHeader: FSYNC_VGCQuery(%s, %lu) failed "
	        "with code %ld, reason %ld\n", dp->name,
	        afs_printable_uint32_lu(volid), afs_printable_int32_ld(code),
		afs_printable_int32_ld(res.hdr.reason));
	    goto done;
	}

	parent = q_res.rw;

    }
    code = FSYNC_VGCDel(dp->name, parent, volid, FSYNC_WHATEVER, &res);
    if (code) {
	Log("VDestroyVolumeDiskHeader: FSYNC_VGCDel(%s, %lu, %lu) failed "
	    "with code %ld reason %ld\n", dp->name,
	    afs_printable_uint32_lu(parent),
	    afs_printable_uint32_lu(volid),
	    afs_printable_int32_ld(code),
	    afs_printable_int32_ld(res.hdr.reason));
    }
#endif /* AFS_DEMAND_ATTACH_FS */

 done:
    return code;
}
Beispiel #5
0
/**
 * Write a file containing the pid of the named process.
 *
 * @param ainst instance name
 * @param aname sub-process name of the instance, may be null
 * @param apid  process id of the newly started process
 *
 * @returns status
 */
int
bozo_CreatePidFile(char *ainst, char *aname, pid_t apid)
{
    int code = 0;
    char *pidfile = NULL;
    FILE *fp;

    pidfile = make_pid_filename(ainst, aname);
    if (!pidfile) {
	return ENOMEM;
    }
    if ((fp = fopen(pidfile, "w")) == NULL) {
	bozo_Log("Failed to open pidfile %s; errno=%d\n", pidfile, errno);
	free(pidfile);
	return errno;
    }
    if (fprintf(fp, "%ld\n", afs_printable_int32_ld(apid)) < 0) {
	code = errno;
    }
    if (fclose(fp) != 0) {
	code = errno;
    }
    free(pidfile);
    return code;
}
Beispiel #6
0
static afs_int32
ListServers(void)
{
    afs_int32 code;
    int i;
    struct VLCallBack vlcb;
    struct VLCallBack spare3;
    bulkaddrs addrs, m_addrs;
    afs_uint32 ip;
    afs_int32 base, index;
    afsUUID m_uuid;
    afs_int32 m_uniq = 0;
    afs_int32 m_nentries;
    char hoststr[16];
    ListAddrByAttributes m_attrs;

    memset(&addrs, 0, sizeof(addrs));
    memset(&spare3, 0, sizeof(spare3));
    code =
	ubik_VL_GetAddrs(client, 0, 0, 0, &vlcb,
		  &server_count, &addrs);
    if (code) {
	printf("Fatal error: could not get list of file servers\n");
	return 1;
    }

    for (i = 0; i < server_count; ++i) {
	ip = addrs.bulkaddrs_val[i];

	if (((ip & 0xff000000) == 0xff000000) && (ip & 0xffff)) {
	    base = (ip >> 16) & 0xff;
	    index = ip & 0xffff;

	    /* server is a multihomed host; query the vldb for its addresses,
	     * and just pick the first one */

	    if ((base >= 0) && (base <= VL_MAX_ADDREXTBLKS) && (index >= 1)
	        && (index <= VL_MHSRV_PERBLK)) {

	        m_attrs.Mask = VLADDR_INDEX;
		m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
		m_nentries = 0;
		m_addrs.bulkaddrs_val = 0;
		m_addrs.bulkaddrs_len = 0;

		code = ubik_VL_GetAddrsU(client, 0, &m_attrs, &m_uuid, &m_uniq,
		                         &m_nentries, &m_addrs);

		if (code || m_addrs.bulkaddrs_len == 0) {
		    printf("Error getting multihomed addresses for server "
		           "%s (index %ld)\n",
			   afs_inet_ntoa_r(m_addrs.bulkaddrs_val[0], hoststr),
			   afs_printable_int32_ld(m_attrs.index));
		    server_id[i] = 0;
		} else {
		    server_id[i] = htonl(m_addrs.bulkaddrs_val[0]);
		}
	    }
	} else {
Beispiel #7
0
/* GetConfigParams
 */
static afs_int32
GetConfigParams(char *filename, afs_int32 port)
{
    char paramFile[256];
    FILE *devFile = 0;
    char line[LINESIZE], cmd[LINESIZE], value[LINESIZE];
    afs_int32 code = 0;
    int cnt;

    /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */
    dump_namecheck = 1;		/* check tape name on dumps */
    queryoperator = 1;		/* can question operator */
    autoQuery = 1;		/* prompt for first tape */
    isafile = 0;		/* Do not dump to a file */
    opencallout = NULL;		/* open  callout routine */
    closecallout = NULL;	/* close callout routine */
    tapemounted = 0;		/* tape is not mounted */
#ifdef xbsa
    BufferSize = (CONF_XBSA ? XBSADFLTBUFFER : BUTM_BLOCKSIZE);
    dumpRestAuthnLevel = rpc_c_protect_level_default;
    xbsaObjectOwner = NULL;	/* bsaObjectOwner */
    appObjectOwner = NULL;	/* appObjectOwner */
    adsmServerName = NULL;	/* TSM server name - same as ADSM */
    xbsaSecToken = NULL;	/* XBSA sercurity token */
    xbsalGName = NULL;		/* XBSA IGName */
#else
    BufferSize = BUTM_BLOCKSIZE;
#endif /*xbsa */
    centralLogFile = NULL;	/* Log for all butcs */
    centralLogIO = 0;		/* Log for all butcs */
    statusSize = 0;		/* size before status message */
    maxpass = PASSESDFLT;	/* dump passes */
    lastLog = 0;		/* separate log for last pass */
    lastLogIO = 0;		/* separate log for last pass */
    groupId = 0;		/* Group id for multiple dumps */

    /* Try opening the CFG_<port> file */
    sprintf(paramFile, "%s_%d", filename, port);
    devFile = fopen(paramFile, "r");
    if (devFile) {
	/* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */
	sprintf(logFile, "%s_%d", lFile, port);
	sprintf(lastLogFile, "%s_%d.lp", lFile, port);
	sprintf(ErrorlogFile, "%s_%d", eFile, port);
    } else if (CONF_XBSA) {
	/* If configured as XBSA, a configuration file CFG_<port> must exist */
	printf("Cannot open configuration file %s", paramFile);
	ERROR_EXIT(1);
    } else {
	/* Try the CFG_<device> name as the device file */
	strcpy(paramFile, filename);
	stringNowReplace(paramFile, globalTapeConfig.device);
	/* Set log names to TL_<device>, TL_<device> and TE_<device> */
	strcpy(logFile, lFile);
	stringNowReplace(logFile, globalTapeConfig.device);
	strcpy(lastLogFile, lFile);
	stringNowReplace(lastLogFile, globalTapeConfig.device);
	strcat(lastLogFile, ".lp");
	strcpy(ErrorlogFile, eFile);
	stringNowReplace(ErrorlogFile, globalTapeConfig.device);

	/* Now open the device file */
	devFile = fopen(paramFile, "r");
	if (!devFile)
	    ERROR_EXIT(0);	/* CFG file doesn't exist for non-XBSA and that's ok */
    }

    /* Read each line of the Configuration file */
    while (fgets(line, LINESIZE - 1, devFile)) {
	cnt = sscanf(line, "%s %s", cmd, value);
	if (cnt != 2) {
	    if (cnt > 0)
		printf("Bad line in %s: %s\n", paramFile, line);
	    continue;
	}

	for (cnt = 0; cnt < strlen(cmd); cnt++)
	    if (islower(cmd[cnt]))
		cmd[cnt] = toupper(cmd[cnt]);

	if (!strcmp(cmd, "NAME_CHECK")) {
	    if (CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a Backup Service\n",
		     cmd);
		continue;
	    }

	    for (cnt = 0; cnt < strlen(value); cnt++)
		if (islower(value[cnt]))
		    value[cnt] = toupper(value[cnt]);

	    if (!strcmp(value, "NO")) {
		printf("Dump tape name check is disabled\n");
		dump_namecheck = 0;
	    } else {
		printf("Dump tape name check is enabled\n");
		dump_namecheck = 1;
	    }
	}

	else if (!strcmp(cmd, "MOUNT")) {
	    if (CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a Backup Service\n",
		     cmd);
		continue;
	    }

	    opencallout = (char *)malloc(strlen(value) + 1);
	    strcpy(opencallout, value);
	    printf("Tape mount callout routine is %s\n", opencallout);
	}

	else if (!strcmp(cmd, "UNMOUNT")) {
	    if (CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a Backup Service\n",
		     cmd);
		continue;
	    }

	    closecallout = (char *)malloc(strlen(value) + 1);
	    strcpy(closecallout, value);
	    printf("Tape unmount callout routine is %s\n", closecallout);
	}

	else if (!strcmp(cmd, "ASK")) {
	    for (cnt = 0; cnt < strlen(value); cnt++)
		if (islower(value[cnt]))
		    value[cnt] = toupper(value[cnt]);

	    if (!strcmp(value, "NO")) {
		printf("Operator queries are disabled\n");
		queryoperator = 0;
	    } else {
		printf("Operator queries are enabled\n");
		queryoperator = 1;
	    }
	}

	else if (!strcmp(cmd, "FILE")) {
	    if (CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a Backup Service\n",
		     cmd);
		continue;
	    }

	    for (cnt = 0; cnt < strlen(value); cnt++)
		if (islower(value[cnt]))
		    value[cnt] = toupper(value[cnt]);

	    if (!strcmp(value, "YES")) {
		printf("Will dump to a file\n");
		isafile = 1;
	    } else {
		printf("Will not dump to a file\n");
		isafile = 0;
	    }
	}

	else if (!strcmp(cmd, "AUTOQUERY")) {
	    if (CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a Backup Service\n",
		     cmd);
		continue;
	    }

	    for (cnt = 0; cnt < strlen(value); cnt++)
		if (islower(value[cnt]))
		    value[cnt] = toupper(value[cnt]);

	    if (!strcmp(value, "NO")) {
		printf("Auto query is disabled\n");
		autoQuery = 0;
	    } else {
		printf("Auto query is enabled\n");
		autoQuery = 1;
	    }
	}

	else if (!strcmp(cmd, "BUFFERSIZE")) {
	    afs_int32 size;
	    afs_int32 tapeblocks;

	    if (!CONF_XBSA) {
		if (atocl(value, 'K', &size)) {
		    fprintf(stderr, "BUFFERSIZE parse error\n");
		    size = 0;
		}

		/* A tapeblock is 16KB. Determine # of tapeblocks. Then
		 * determine BufferSize needed for that many tapeblocks.
		 */
		tapeblocks = size / 16;
		if (tapeblocks <= 0)
		    tapeblocks = 1;
		printf("BUFFERSIZE is %u KBytes\n", (tapeblocks * 16));
		BufferSize = tapeblocks * BUTM_BLOCKSIZE;
	    } else {
#ifdef xbsa
		if (atocl(value, 'B', &size)) {
		    fprintf(stderr, "BUFFERSIZE parse error\n");
		    size = 0;
		}
		if (size < XBSAMINBUFFER)
		    size = XBSAMINBUFFER;
		if (size > XBSAMAXBUFFER)
		    size = XBSAMAXBUFFER;
		printf("XBSA buffer size is %u Bytes\n", size);
		BufferSize = size;
#endif
	    }
	}
#ifndef xbsa
	/* All the xbsa spacific parameters */
	else if (!strcmp(cmd, "TYPE") || !strcmp(cmd, "NODE")
		 || !strcmp(cmd, "SERVER") || !strcmp(cmd, "PASSWORD")
		 || !strcmp(cmd, "PASSFILE") || !strcmp(cmd, "MGMTCLASS")) {
	    printf("This binary does not have XBSA support\n");
	    return 1;
	}
#else
	else if (!strcmp(cmd, "TYPE")) {	/* required for XBSA */
	    if (!CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a tape drive\n",
		     cmd);
		continue;
	    }

	    for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
		if (islower(value[cnt]))
		    value[cnt] = toupper(value[cnt]);

	    if (strcmp(value, "TSM") == 0) {
		xbsaType = XBSA_SERVER_TYPE_ADSM;	/* Known XBSA server type */
	    } else {
		printf("Configuration file error, %s %s is not recognized\n",
		       cmd, value);
		xbsaType = XBSA_SERVER_TYPE_UNKNOWN;
	    }
	    printf("XBSA type is %s\n",
		   ((xbsaType ==
		     XBSA_SERVER_TYPE_UNKNOWN) ? "Unknown" : value));
	}

	else if (!strcmp(cmd, "NODE")) {
	    if (!CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a tape drive\n",
		     cmd);
		continue;
	    }
	    xbsaObjectOwner = malloc(strlen(value) + 1);
	    strcpy(xbsaObjectOwner, value);
	    printf("XBSA node is %s\n", xbsaObjectOwner);
	}

	else if (!strcmp(cmd, "SERVER")) {	/* required for XBSA */
	    if (!CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a tape drive\n",
		     cmd);
		continue;
	    }
	    adsmServerName = malloc(strlen(value) + 1);
	    strcpy(adsmServerName, value);
	    printf("XBSA server is %s\n", adsmServerName);
	}

	else if (!strcmp(cmd, "PASSWORD")) {	/* This or PASSFILE required for XBSA */
	    if (!CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a tape drive\n",
		     cmd);
		continue;
	    }
	    if (xbsaSecToken) {
		printf
		    ("Warning: The %s parameter is ignored. Already read password\n",
		     cmd);
		continue;
	    }

	    xbsaSecToken = malloc(strlen(value) + 1);
	    strcpy(xbsaSecToken, value);
	    printf("XBSA Password has been read\n");
	}

	else if (!strcmp(cmd, "PASSFILE")) {	/* This or PASSWORD required for XBSA */
	    FILE *pwdFile;
	    if (!CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a tape drive\n",
		     cmd);
		continue;
	    }
	    if (xbsaSecToken) {
		printf
		    ("Warning: The %s parameter is ignored. Already read password\n",
		     cmd);
		continue;
	    }

	    pwdFile = fopen(value, "r");
	    if (!pwdFile) {
		printf
		    ("Configuration file error, cannot open password file %s\n",
		     value);
		ERROR_EXIT(1);
	    }
	    xbsaSecToken = malloc(LINESIZE);
	    if (!fscanf(pwdFile, "%s", xbsaSecToken)) {
		printf
		    ("Configuration file error, cannot read password file %s\n",
		     value);
		ERROR_EXIT(1);
	    }
	    printf("XBSA password retrieved from password file\n");
	}

	else if (!strcmp(cmd, "MGMTCLASS")) {	/* XBSA */
	    if (!CONF_XBSA) {
		printf
		    ("Warning: The %s parameter is ignored with a tape drive\n",
		     cmd);
		continue;
	    }
	    xbsalGName = malloc(strlen(value) + 1);
	    strcpy(xbsalGName, value);
	    printf("XBSA management class is %s\n", xbsalGName);
	}
#endif

	else if (!strcmp(cmd, "MAXPASS")) {
	    maxpass = SafeATOL(value);
	    if (maxpass < PASSESMIN)
		maxpass = PASSESMIN;
	    if (maxpass > PASSESMAX)
		maxpass = PASSESMAX;
	    printf("MAXPASS is %d\n", maxpass);
	}

	else if (!strcmp(cmd, "GROUPID")) {
	    groupId = SafeATOL(value);
	    if ((groupId < MINGROUPID) || (groupId > MAXGROUPID)) {
		printf("Configuration file error, %s %s is invalid\n", cmd,
		       value);
		ERROR_EXIT(1);
	    }
	    printf("Group Id is %d\n", groupId);
	}

	else if (!strcmp(cmd, "LASTLOG")) {
	    for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
		if (islower(value[cnt]))
		    value[cnt] = toupper(value[cnt]);

	    lastLog = (strcmp(value, "YES") == 0);
	    printf("Will %sgenerate a last log\n", (lastLog ? "" : "not "));
	}

	else if (!strcmp(cmd, "CENTRALLOG")) {
	    centralLogFile = malloc(strlen(value) + 1);
	    strcpy(centralLogFile, value);
	    printf("Central log file is %s\n", centralLogFile);
	}

	else if (!strcmp(cmd, "STATUS")) {
	    if (atocl(value, 'B', &statusSize)) {
		fprintf(stderr, "STATUS parse error\n");
		statusSize = 0;
	    }
	    if (statusSize < MINSTATUS)
		statusSize = MINSTATUS;
	    if (statusSize > MAXSTATUS)
		statusSize = MAXSTATUS;
	}

	else {
	    printf("Warning: Unrecognized configuration parameter: %s", line);
	}
    }				/*fgets */

    if (statusSize) {
	/* Statussize is in bytes and requires that BufferSize be set first */
	statusSize *= BufferSize;
	if (statusSize < 0)
	    statusSize = 0x7fffffff;	/*max size */
	printf("Status every %ld Bytes\n", afs_printable_int32_ld(statusSize));
    }

  error_exit:
    if (devFile)
	fclose(devFile);

    /* If the butc is configured as XBSA, check for required parameters */
#ifdef xbsa
    if (!code && CONF_XBSA) {
	if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
	    printf
		("Configuration file error, the TYPE parameter must be specified, or\n");
	    printf("an entry must exist in %s for port %d\n", tapeConfigFile,
		   port);
	    code = 1;
	}
	if (!adsmServerName) {
	    printf
		("Configuration file error, the SERVER parameter must be specified\n");
	    code = 1;
	}
	if (!xbsaSecToken) {
	    printf
		("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n");
	    code = 1;
	}
    }
#endif /*xbsa */
    return (code);
}
Beispiel #8
0
/**
 * verify that the fileserver still thinks we have a volume checked out.
 *
 * In DAFS, a non-fileserver program accesses a volume by checking it out from
 * the fileserver (FSYNC_VOL_OFF or FSYNC_VOL_NEEDVOLUME), and then locks the
 * volume. There is a possibility that the fileserver crashes or restarts for
 * some reason between volume checkout and locking; if this happens, the
 * fileserver could attach the volume before we had a chance to lock it. This
 * function serves to detect if this has happened; it must be called after
 * volume checkout and locking to make sure the fileserver still thinks we
 * have the volume. (If it doesn't, we should try to check it out again.)
 *
 * @param[in] volume    volume ID
 * @param[in] partition partition name string
 * @param[in] command   the command that was used to checkout the volume
 * @param[in] reason    the reason code used to checkout the volume
 *
 * @return operation status
 *  @retval SYNC_OK the fileserver could not have attached the volume since
 *                  it was checked out (either it thinks it is still checked
 *                  out, or it doesn't know about the volume)
 *  @retval SYNC_DENIED fileserver may have restarted since checkout; checkout
 *                      should be reattempted
 *  @retval SYNC_COM_ERROR internal/fatal error
 */
afs_int32
FSYNC_VerifyCheckout(VolumeId volume, char * partition,
                     afs_int32 command, afs_int32 reason)
{
    SYNC_response res;
    FSSYNC_VolOp_info vop;
    afs_int32 code;
    afs_int32 pid;

    res.hdr.response_len = sizeof(res.hdr);
    res.payload.buf = &vop;
    res.payload.len = sizeof(vop);

    code = FSYNC_VolOp(volume, partition, FSYNC_VOL_QUERY_VOP, FSYNC_WHATEVER, &res);
    if (code != SYNC_OK) {
        if (res.hdr.reason == FSYNC_NO_PENDING_VOL_OP) {
            Log("FSYNC_VerifyCheckout: fileserver claims no vop for vol %lu "
                "part %s; fileserver may have restarted since checkout\n",
                afs_printable_uint32_lu(volume), partition);
            return SYNC_DENIED;
        }

        if (res.hdr.reason == FSYNC_UNKNOWN_VOLID ||
                res.hdr.reason == FSYNC_WRONG_PART) {
            /* if the fileserver does not know about this volume on this
             * partition, there's no way it could have attached it, so we're
             * fine */
            return SYNC_OK;
        }

        Log("FSYNC_VerifyCheckout: FSYNC_VOL_QUERY_VOP failed for vol %lu "
            "part %s with code %ld reason %ld\n",
            afs_printable_uint32_lu(volume), partition,
            afs_printable_int32_ld(code),
            afs_printable_int32_ld(res.hdr.reason));
        return SYNC_COM_ERROR;
    }

    pid = getpid();

    /* Check if the current vol op is us. Checking pid is probably enough, but
     * be a little bit paranoid. We could also probably check tid, but I'm not
     * completely confident of its reliability on all platforms (on pthread
     * envs, we coerce a pthread_t to an afs_int32, which is not guaranteed
     * to mean anything significant). */

    if (vop.com.programType == programType && vop.com.pid == pid &&
            vop.com.command == command && vop.com.reason == reason) {

        /* looks like the current pending vol op is the same one as the one
         * with which we checked it out. success. */
        return SYNC_OK;
    }

    Log("FSYNC_VerifyCheckout: vop for vol %lu part %s does not match "
        "expectations (got pt %ld pid %ld cmd %ld reason %ld, but expected "
        "pt %ld pid %ld cmd %ld reason %ld); fileserver may have restarted "
        "since checkout\n", afs_printable_uint32_lu(volume), partition,
        afs_printable_int32_ld(vop.com.programType),
        afs_printable_int32_ld(vop.com.pid),
        afs_printable_int32_ld(vop.com.command),
        afs_printable_int32_ld(vop.com.reason),
        afs_printable_int32_ld(programType),
        afs_printable_int32_ld(pid),
        afs_printable_int32_ld(command),
        afs_printable_int32_ld(reason));

    return SYNC_DENIED;
}
Beispiel #9
0
/**
 * write an existing volume disk header.
 *
 * @param[in] hdr   volume disk header
 * @param[in] dp    disk partition object
 *
 * @return operation status
 *    @retval 0 success
 *    @retval ENOENT volume header doesn't exist
 *    @retval EIO failed to write volume header
 */
afs_int32
VWriteVolumeDiskHeader(VolumeDiskHeader_t * hdr,
		       struct DiskPartition64 * dp)
{
    afs_int32 code;

#ifdef AFS_DEMAND_ATTACH_FS
    VolumeDiskHeader_t oldhdr;
    int delvgc = 0, addvgc = 0;
    SYNC_response res;

    /* first, see if anything with the volume IDs have changed; if so, we
     * need to update the VGC */

    code = VReadVolumeDiskHeader(hdr->id, dp, &oldhdr);
    if (code == 0 && (oldhdr.id != hdr->id || oldhdr.parent != hdr->parent)) {
	/* the vol id or parent vol id changed; need to delete the VGC entry
	 * for the old vol id/parent, and add the new one */
	delvgc = 1;
	addvgc = 1;

    } else if (code) {
	/* couldn't get the old header info; add the new header info to the
	 * VGC in case it hasn't been added yet */
	addvgc = 1;
    }

#endif /* AFS_DEMAND_ATTACH_FS */

    code = _VWriteVolumeDiskHeader(hdr, dp, 0);
    if (code) {
	goto done;
    }

#ifdef AFS_DEMAND_ATTACH_FS
    if (delvgc) {
	memset(&res, 0, sizeof(res));
	code = FSYNC_VGCDel(dp->name, oldhdr.parent, oldhdr.id, FSYNC_WHATEVER, &res);

	/* unknown vol id is okay; it just further suggests the old header
	 * data was bogus, which is fine since we're trying to fix it */
	if (code && res.hdr.reason != FSYNC_UNKNOWN_VOLID) {
	    Log("VWriteVolumeDiskHeader: FSYNC_VGCDel(%s, %lu, %lu) "
	        "failed with code %ld reason %ld\n", dp->name,
	        afs_printable_uint32_lu(oldhdr.parent),
	        afs_printable_uint32_lu(oldhdr.id),
	        afs_printable_int32_ld(code),
	        afs_printable_int32_ld(res.hdr.reason));
	}

    }
    if (addvgc) {
	memset(&res, 0, sizeof(res));
	code = FSYNC_VGCAdd(dp->name, hdr->parent, hdr->id, FSYNC_WHATEVER, &res);
	if (code) {
	    Log("VWriteVolumeDiskHeader: FSYNC_VGCAdd(%s, %lu, %lu) "
	        "failed with code %ld reason %ld\n", dp->name,
	        afs_printable_uint32_lu(hdr->parent),
	        afs_printable_uint32_lu(hdr->id),
	        afs_printable_int32_ld(code),
		afs_printable_int32_ld(res.hdr.reason));
	}
    }

#endif /* AFS_DEMAND_ATTACH_FS */

 done:
    return code;
}
Beispiel #10
0
int
main(int argc, char **argv)
{
    register afs_int32 code;
    struct ubik_client *cstruct = 0;
    afs_uint32 serverList[MAXSERVERS];
    struct rx_connection *serverconns[MAXSERVERS];
    struct rx_securityClass *sc;
    register afs_int32 i;
    afs_int32 temp;

    if (argc == 1) {
	printf
	    ("uclient: usage is 'uclient -servers ... [-try] [-get] [-inc] [-minc] [-trunc]\n");
	exit(0);
    }
#ifdef AFS_NT40_ENV
    /* initialize winsock */
    if (afs_winsockInit() < 0)
	return -1;
#endif
    /* first parse '-servers <server-1> <server-2> ... <server-n>' from command line */
    code = ubik_ParseClientList(argc, argv, serverList);
    if (code) {
	printf("could not parse server list, code %d\n", code);
	exit(1);
    }
    rx_Init(0);
    sc = rxnull_NewClientSecurityObject();
    for (i = 0; i < MAXSERVERS; i++) {
	if (serverList[i]) {
	    serverconns[i] =
		rx_NewConnection(serverList[i], htons(3000), USER_SERVICE_ID,
				 sc, 0);
	} else {
	    serverconns[i] = (struct rx_connection *)0;
	    break;
	}
    }

    /* next, pass list of server rx_connections (in serverconns), and
     * a place to put the returned client structure that we'll use in
     * all of our rpc calls (via ubik_Calll) */
    code = ubik_ClientInit(serverconns, &cstruct);

    /* check code from init */
    if (code) {
	printf("ubik client init failed with code %d\n", code);
	exit(1);
    }

    /* parse command line for our own operations */
    for (i = 1; i < argc; i++) {
	if (!strcmp(argv[i], "-inc")) {
	    /* use ubik_Call to do the work, finding an up server and handling
	     * the job of finding a sync site, if need be */
	    code = ubik_SAMPLE_Inc(cstruct, 0);
	    printf("return code is %d\n", code);
	} else if (!strcmp(argv[i], "-try")) {
	    code = ubik_SAMPLE_Test(cstruct, 0);
	    printf("return code is %d\n", code);
	} else if (!strcmp(argv[i], "-qget")) {
	    code = ubik_SAMPLE_QGet(cstruct, 0, &temp);
	    printf("got quick value %d (code %d)\n", temp, code);
	} else if (!strcmp(argv[i], "-get")) {
	    code = ubik_SAMPLE_Get(cstruct, 0, &temp);
	    printf("got value %d (code %d)\n", temp, code);
	} else if (!strcmp(argv[i], "-trunc")) {
	    code = ubik_SAMPLE_Trun(cstruct, 0);
	    printf("return code is %d\n", code);
	} else if (!strcmp(argv[i], "-minc")) {
	    afs_int32 temp;
	    struct timeval tv;
	    tv.tv_sec = 1;
	    tv.tv_usec = 0;
	    printf("ubik_client: Running minc...\n");

	    while (1) {
		temp = 0;
		code = ubik_SAMPLE_Get(cstruct, 0, &temp);
		if (code != 0) {
		    printf("SAMPLE_Get #1 failed with code %ld\n",
			   afs_printable_int32_ld(code));
		} else {
		    printf("SAMPLE_Get #1 succeeded, got value %ld\n",
			   afs_printable_int32_ld(temp));
		}

		temp = 0;
		code = ubik_SAMPLE_Inc(cstruct, 0);
		if (code != 0) {
		    printf("SAMPLE_Inc #1 failed with code %ld\n", 
			   afs_printable_int32_ld(code));
		} else {
		    printf("SAMPLE_Inc #1 succeeded, incremented integer\n");
		}
		temp = 0;
		code = ubik_SAMPLE_Get(cstruct, 0, &temp);
		if (code != 0) {
		    printf("SAMPLE_Get #2 failed with code %ld\n",
			   afs_printable_int32_ld(code));
		} else {
		    printf("SAMPLE_Get #2 succeeded, got value %ld\n",
			   afs_printable_int32_ld(temp));
		}

		temp = 0;
		code = ubik_SAMPLE_Inc(cstruct, 0);
		if (code != 0)
		    printf("SAMPLE_Inc #2 failed with code %ld\n", 
			   afs_printable_int32_ld(code));
		else
		    printf("SAMPLE_Inc #2 succeeded, incremented integer\n");

		tv.tv_sec = 1;
		tv.tv_usec = 0;
#ifdef AFS_PTHREAD_ENV
		select(0, 0, 0, 0, &tv);
#else
		IOMGR_Select(0, 0, 0, 0, &tv);
#endif
		printf("Repeating the SAMPLE operations again...\n");
	    }
	} else if (!strcmp(argv[i], "-mget")) {
	    afs_int32 temp;
	    struct timeval tv;
	    tv.tv_sec = 1;
	    tv.tv_usec = 0;
	    while (1) {
		code = ubik_SAMPLE_Get(cstruct, 0, &temp);
		printf("got value %d (code %d)\n", temp, code);

		code = ubik_SAMPLE_Inc(cstruct, 0);
		printf("update return code is %d\n", code);

		code = ubik_SAMPLE_Get(cstruct, 0, &temp);
		printf("got value %d (code %d)\n", temp, code);

		code = ubik_SAMPLE_Get(cstruct, 0, &temp);
		printf("got value %d (code %d)\n", temp, code);

		tv.tv_sec = 1;
		tv.tv_usec = 0;
#ifdef AFS_PTHREAD_ENV
		select(0, 0, 0, 0, &tv);
#else
		IOMGR_Select(0, 0, 0, 0, &tv);
#endif
	    }
	}
    }
    return 0;
}
Beispiel #11
0
static afs_int32
SendNotifierData(int fd, struct bnode_proc *tp)
{
    struct bnode *tb = tp->bnode;
    char buffer[1000], *bufp = buffer, *buf1;
    int len;

    /*
     * First sent out the bnode_proc struct
     */
    (void)sprintf(bufp, "BEGIN bnode_proc\n");
    bufp += strlen(bufp);
    (void)sprintf(bufp, "comLine: %s\n", tp->comLine);
    bufp += strlen(bufp);
    if (!(buf1 = tp->coreName))
	buf1 = "(null)";
    (void)sprintf(bufp, "coreName: %s\n", buf1);
    bufp += strlen(bufp);
    (void)sprintf(bufp, "pid: %ld\n", afs_printable_int32_ld(tp->pid));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "lastExit: %ld\n", afs_printable_int32_ld(tp->lastExit));
    bufp += strlen(bufp);
#ifdef notdef
    (void)sprintf(bufp, "lastSignal: %ld\n", afs_printable_int32_ld(tp->lastSignal));
    bufp += strlen(bufp);
#endif
    (void)sprintf(bufp, "flags: %ld\n", afs_printable_int32_ld(tp->flags));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "END bnode_proc\n");
    bufp += strlen(bufp);
    len = (int)(bufp - buffer);
    if (write(fd, buffer, len) < 0) {
	return -1;
    }

    /*
     * Now sent out the bnode struct
     */
    bufp = buffer;
    (void)sprintf(bufp, "BEGIN bnode\n");
    bufp += strlen(bufp);
    (void)sprintf(bufp, "name: %s\n", tb->name);
    bufp += strlen(bufp);
    (void)sprintf(bufp, "rsTime: %ld\n", afs_printable_int32_ld(tb->rsTime));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "rsCount: %ld\n", afs_printable_int32_ld(tb->rsCount));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "procStartTime: %ld\n", afs_printable_int32_ld(tb->procStartTime));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "procStarts: %ld\n", afs_printable_int32_ld(tb->procStarts));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "lastAnyExit: %ld\n", afs_printable_int32_ld(tb->lastAnyExit));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "lastErrorExit: %ld\n", afs_printable_int32_ld(tb->lastErrorExit));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "errorCode: %ld\n", afs_printable_int32_ld(tb->errorCode));
    bufp += strlen(bufp);
    (void)sprintf(bufp, "errorSignal: %ld\n", afs_printable_int32_ld(tb->errorSignal));
    bufp += strlen(bufp);
/*
    (void) sprintf(bufp, "lastErrorName: %s\n", tb->lastErrorName);
    bufp += strlen(bufp);
*/
    (void)sprintf(bufp, "goal: %d\n", tb->goal);
    bufp += strlen(bufp);
    (void)sprintf(bufp, "END bnode\n");
    bufp += strlen(bufp);
    len = (int)(bufp - buffer);
    if (write(fd, buffer, len) < 0) {
	return -1;
    }
    return 0;
}