Commit bcccbd8f authored by Steven Murray's avatar Steven Murray Committed by Steven Murray
Browse files

Implemented the first version of the logic for marshalling an RMC_ACS_MOUNT

message as a result of calling the rmc_mnt() with a drive string for a drive
within an ACS compatible tape library.
parent a7615b30
......@@ -33,15 +33,15 @@
/* Request types */
#define RMC_GETGEOM 1 /* Get robot geometry */
#define RMC_FINDCART 2 /* Find cartridge(s) */
#define RMC_READELEM 3 /* Read element status */
#define RMC_MOUNT 4 /* Mount request */
#define RMC_UNMOUNT 5 /* Unmount request */
#define RMC_EXPORT 6 /* Export tape request */
#define RMC_IMPORT 7 /* Import tape request */
#define RMC_GENERICMOUNT 8 /* Generic (SCSI or ACS) mount request */
#define RMC_GENERICUNMOUNT 9 /* Generic (SCSI or ACS) mount request */
#define RMC_GETGEOM 1 /* Get robot geometry */
#define RMC_FINDCART 2 /* Find cartridge(s) */
#define RMC_READELEM 3 /* Read element status */
#define RMC_MOUNT 4 /* Mount request */
#define RMC_UNMOUNT 5 /* Unmount request */
#define RMC_EXPORT 6 /* Export tape request */
#define RMC_IMPORT 7 /* Import tape request */
#define RMC_ACS_MOUNT 8 /* ACS mount request */
#define RMC_ACS_UNMOUNT 9 /* ACS unmount request */
/* SCSI media changer server reply types */
......
/******************************************************************************
* h/rmc_find_char.h
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
/******************************************************************************
* Please note that this file is part of the internal API of the rmc daemon
* and its client software and should therefore not be distributed to end users
*****************************************************************************/
#ifndef RMC_FIND_CHAR_H
#define RMC_FIND_CHAR_H 1
/**
* Returns the index of the specified character within the specified string.
* The search for the character is performed from left to right and stops at the
* first coccurence of the character.
*
* @param str The string to be searched.
* @param c The character to be seacrhed for.
* @return The index of the character if it was found else -1 if not.
*/
int rmc_find_char(const char *const str, const char c);
#endif /* RMC_FIND_CHAR_H */
/******************************************************************************
* h/rmc_get_acs_drive_id.h
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
/******************************************************************************
* Please note that this file is part of the internal API of the rmc daemon
* and its client software and should therefore not be distributed to end users
*****************************************************************************/
#ifndef RMC_GET_ACS_DRIVE_ID_H
#define RMC_GET_ACS_DRIVE_ID_H 1
/**
* Structure representing the identifier of a drive withn an ACS compatible
* tape library.
*/
struct rmc_acs_drive_id {
int acs;
int lsm;
int panel;
int transport;
};
/**
* Returns the drive id of the specified drive string of the form:
*
* acs@rmc_host,acs,lsm,panel,transport
*
* There are three RMC loader types, namely acs, manual and smc. The drive
* string is expected to be in one of the following forms respectively:
*
* acs@rmc_host[:rmc_port],ACS_NUMBER,LSM_NUMBER,PANEL_NUMBER,TRANSPORT_NUMBER
* manual
* smc@rmc_host[:rmc_port],drive_ordinal
*
* @return The loader type.
*/
int rmc_get_acs_drive_id(const char *const drive,
struct rmc_acs_drive_id *const drive_id);
#endif /* RMC_GET_ACS_DRIVE_ID_H */
/******************************************************************************
* h/rmc_get_loader_type.h
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
/******************************************************************************
* Please note that this file is part of the internal API of the rmc daemon
* and its client software and should therefore not be distributed to end users
*****************************************************************************/
#ifndef RMC_GET_LOADER_TYPE_H
#define RMC_GET_LOADER_TYPE_H 1
typedef enum {
RMC_LOADER_TYPE_ACS,
RMC_LOADER_TYPE_MANUAL,
RMC_LOADER_TYPE_SMC,
RMC_LOADER_TYPE_UNKNOWN} rmc_loader_type;
/**
* Returns the loader type of the specified drive string.
*
* There are three RMC loader types, namely acs, manual and smc. The drive
* string is expected to be in one of the following forms respectively:
*
* acs@rmc_host[:rmc_port],ACS_NUMBER,LSM_NUMBER,PANEL_NUMBER,TRANSPORT_NUMBER
* manual
* smc@rmc_host[:rmc_port],drive_ordinal
*
* @param drive The drive string.
* @return The loader type.
*/
rmc_loader_type rmc_get_loader_type(const char *const drive);
#endif /* RMC_GET_LOADER_TYPE_H */
/******************************************************************************
* h/rmc_get_rmc_host_of_drive.h
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
/******************************************************************************
* Please note that this file is part of the internal API of the rmc daemon
* and its client software and should therefore not be distributed to end users
*****************************************************************************/
#ifndef RMC_GET_RMC_HOST_OF_DRIVE_H
#define RMC_GET_RMC_HOST_OF_DRIVE_H 1
/**
* Returns the rmc host of the specified drive string. The drive string either
* starts with:
*
* acs@rmc_host,
* or:
*
* smc@rmc_host,
*
* @param drive The drive string
* @param rmc_host_buf Output parameter. The buffer into which the rmc host
* should be written as a null terminated string.
* @param rmc_host_buflen The length of the rmc host buffer.
* @return 0 on success and -1 on failure.
*/
int rmc_get_rmc_host_of_drive(const char *const drive,
char *const rmc_host_buf, const int rmc_host_buflen);
#endif /* RMC_GET_RMC_HOST_OF_DRIVE_H */
......@@ -40,7 +40,7 @@ int rmc_srv_import(const struct rmc_srv_rqst_context *const rqst_context);
int rmc_srv_mount(const struct rmc_srv_rqst_context *const rqst_context);
int rmc_srv_readelem(const struct rmc_srv_rqst_context *const rqst_context);
int rmc_srv_unmount(const struct rmc_srv_rqst_context *const rqst_context);
int rmc_srv_mnt(const struct rmc_srv_rqst_context *const rqst_context);
int rmc_srv_unmnt(const struct rmc_srv_rqst_context *const rqst_context);
int rmc_srv_acs_mnt(const struct rmc_srv_rqst_context *const rqst_context);
int rmc_srv_acs_unmnt(const struct rmc_srv_rqst_context *const rqst_context);
#endif
/******************************************************************************
* rmc/rmc_find_char.c
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
#include "h/rmc_find_char.h"
#include <string.h>
int rmc_find_char(const char *const str, const char c) {
if(NULL != str) {
const int str_len = strlen(str);
int i = 0;
for(i = 0; i < str_len; i++) {
if(c == str[i]) {
return i;
}
}
}
return -1;
}
/******************************************************************************
* rmc/rmc_get_acs_drive_id.c
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
#include "h/rmc_get_acs_drive_id.h"
#include <string.h>
/**
* A simple function that converts the string representation of the unsigned
* integer in the specified character buffer to an integer.
*
* @return A value of 0 or greater than 0 if the conversion was a success or -1
* if the conversion was not a success.
*/
static int rmc_buf2uint(const char *const buf, int buflen) {
int i = 0;
int value = 0;
int multipler = 1;
/* Fail conversion if there is nothing to convert */
if(NULL == buf || 0 == buflen) {
return -1;
}
for(i = 0; i < buflen; i++) {
const char c = buf[i];
/* Fail conversion if the character is not a decimal digit */
if(c < '0' || c > '9') {
return -1;
}
value *= multipler;
value += (c - '0');
multipler *= 10;
}
return value;
}
int rmc_get_acs_drive_id(const char *const drive,
struct rmc_acs_drive_id *const drive_id) {
int str_len = 0;
int i = 0;
int nbCommas = 0;
int commaIndex[4];
/* Fail if there is nothing to work on */
if(NULL == drive) {
return -1;
}
str_len = strlen(drive);
/* An acs drive string starts with "acs@" */
/* */
/* Fail if the first 4 characters do not exist or are not as expected */
if(4 > str_len || strncmp("acs@", drive, 4)) {
return -1;
}
/* The drive string should be of the form */
/* "acs@rmc_host,acs,lsm,panel,transport" */
/* therefore there should be 4 commas (',') */
/* Find the expected 4 commas */
for(i=0; i < str_len; i++) {
if(',' == drive[i]) {
/* Fail if there are too many commas */
if(4 < nbCommas) {
return -1;
}
commaIndex[nbCommas] = i;
nbCommas++;
}
}
/* Fail if there are too few commas */
if(4 != nbCommas) {
return -1;
}
/* Fail if the rmc_host has zero length */
if(0 == commaIndex[0] - 3 /* index of at sign ('@') */) {
return -1;
}
/* Try to convert the 4 drive id numbers to integers */
drive_id->acs = rmc_buf2uint(drive + commaIndex[0] + 1,
commaIndex[1] - commaIndex[0]);
drive_id->lsm = rmc_buf2uint(drive + commaIndex[1] + 1,
commaIndex[2] - commaIndex[1]);
drive_id->panel = rmc_buf2uint(drive + commaIndex[2] + 1,
commaIndex[3] - commaIndex[2]);
drive_id->transport = rmc_buf2uint(drive + commaIndex[3] + 1,
str_len - 1 - commaIndex[3]);
/* Fail if one of the drive id numbers could not be converted */
if( -1 == drive_id->acs ||
-1 == drive_id->lsm ||
-1 == drive_id->panel ||
-1 == drive_id->transport) {
return -1;
}
return 0;
}
/******************************************************************************
* h/rmc_get_loader_type.h
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
#include "h/rmc_get_loader_type.h"
#include <string.h>
rmc_loader_type rmc_get_loader_type(const char *const drive) {
if(strncmp("acs@", drive, 3) == 0) {
return RMC_LOADER_TYPE_ACS;
} else if(strcmp("manual", drive) == 0) {
return RMC_LOADER_TYPE_MANUAL;
} else if(strncmp("smc@", drive, 3) == 0) {
return RMC_LOADER_TYPE_SMC;
} else {
return RMC_LOADER_TYPE_UNKNOWN;
}
}
/******************************************************************************
* rmc/rmc_get_rmc_host_of_drive.c
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Steven.Murray@cern.ch
*****************************************************************************/
#include "h/rmc_find_char.h"
#include "h/rmc_get_rmc_host_of_drive.h"
#include <string.h>
int rmc_get_rmc_host_of_drive(const char *const drive,
char *const rmc_host_buf, const int rmc_host_buflen) {
int indexOfComma = 0;
int rmc_host_len = 0;
/* Fail if there is nothing to work on */
if(NULL == drive || NULL == rmc_host_buf || 0 == rmc_host_buflen) {
return -1;
}
/* Fail if the drive string does not start with either "acs@" or */
/* "smc@" */
if(strncmp("acs@", drive, 4) && strncmp("smc@", drive, 4)) {
return -1;
}
/* The rmc_host should follow the at sign ('@') and be terminated by */
/* a comma (',') for example "acs@rmc_host," */
indexOfComma = rmc_find_char(drive, ',');
rmc_host_len = indexOfComma - 3 /* index of the at sign */ - 1;
if( 0 >= rmc_host_len || /* rmc_host contains no characters */
rmc_host_buflen <= rmc_host_len) { /* rmc_host is too long */
return -1;
}
memcpy(rmc_host_buf, drive + 4, rmc_host_len);
rmc_host_buf[rmc_host_len] = '\0';
return 0;
}
......@@ -32,27 +32,61 @@
#include "h/marshall.h"
#include "h/rmc_api.h"
#include "h/rmc_constants.h"
#include "h/rmc_find_char.h"
#include "h/rmc_get_acs_drive_id.h"
#include "h/rmc_get_rmc_host_of_drive.h"
#include "h/rmc_get_loader_type.h"
#include "h/serrno.h"
#include <errno.h>
#include <string.h>
static int rmc_acs_mnt(const char *const server, const char *const vid,
const char *const drive);
static int rmc_manual_mnt(const char *const server, const char *const vid,
const char *const drive);
static int rmc_smc_mnt(const char *const server, const char *const vid,
const char *const drive);
int rmc_mnt(
const char *const server,
const char *const vid,
const char *const drive)
{
switch(rmc_get_loader_type(drive)) {
case RMC_LOADER_TYPE_ACS:
return rmc_acs_mnt(server, vid, drive);
case RMC_LOADER_TYPE_MANUAL:
return rmc_manual_mnt(server, vid, drive);
case RMC_LOADER_TYPE_SMC:
return rmc_smc_mnt(server, vid, drive);
default:
errno = ERMCUNREC;
serrno = errno;
return -1;
}
}
static int rmc_acs_mnt(
const char *const server,
const char *const vid,
const char *const drive) {
const gid_t gid = getgid();
const uid_t uid = getuid();
/* The total length of the fixed size members of the request message */
/* is Magic (4 bytes) + request ID (4 bytes) + length (4 bytes) + */
/* uid (4 bytes) + gid (4 bytes) = 20 bytes */
const int msglen = 20 + strlen(vid) + 1 + strlen(drive) + 1;
/* is Magic (4 bytes) + request ID (4 bytes) + msglen (4 bytes) + */
/* uid (4 bytes) + gid (4 bytes) + ACS number (4 bytes) + LSM number */
/* (4 bytes) + panel number (4 bytes) + transport number (4 bytes) = */
/* 40 bytes */
const int msglen = 40 + strlen(vid);
char repbuf[1];
char *sbp = NULL;
char sendbuf[RMC_REQBUFSZ];
char rmc_host[CA_MAXHOSTNAMELEN+1];
struct rmc_acs_drive_id drive_id = {0, 0, 0, 0};
/* Consider the function arguments invalid if the total size of the */
/* request message would be greater than RMC_REQBUFSZ */
......@@ -68,17 +102,28 @@ int rmc_mnt(
return -1;
}
if(rmc_get_rmc_host_of_drive(drive, rmc_host, sizeof(rmc_host))) {
return -1;
}
if(rmc_get_acs_drive_id(drive, &drive_id)) {
return -1;
}
/* Build request header */
sbp = sendbuf;
marshall_LONG (sbp, RMC_MAGIC);
marshall_LONG (sbp, RMC_GENERICMOUNT);
marshall_LONG (sbp, RMC_ACS_MOUNT);
marshall_LONG (sbp, msglen);
/* Build request body */
marshall_LONG (sbp, uid);