MGM/CONSOLE/DOC: add new structure to the recycle bin, update documentation -…

MGM/CONSOLE/DOC: add new structure to the recycle bin, update documentation - supports old and new style entries at the same time
parent 51aad268
Pipeline #467653 passed with stages
in 34 minutes and 37 seconds
......@@ -59,6 +59,11 @@ public:
Init(path);
}
Path(std::string path)
{
Init(path.c_str());
}
//----------------------------------------------------------------------------
//! Destructor
//----------------------------------------------------------------------------
......@@ -95,11 +100,13 @@ public:
//----------------------------------------------------------------------------
//! Return constracted path replacing all '/' with '::'
//----------------------------------------------------------------------------
std::string
std::string
GetContractedPath()
{
XrdOucString contractedpath = GetPath();
while (contractedpath.replace("/","::")) {}
while (contractedpath.replace("/", "::")) {}
return contractedpath.c_str();
}
......@@ -327,7 +334,7 @@ public:
struct stat buf;
if (stat(GetParentPath(), &buf)) {
for (int i = GetSubPathSize()-1; i >= 0; i--) {
for (int i = GetSubPathSize() - 1; i >= 0; i--) {
// go backwards until the directory exists
if (!stat(GetSubPath(i), &buf)) {
// this exists
......
......@@ -39,6 +39,7 @@ com_recycle(char* arg1)
std::vector<std::string> options;
bool monitoring = false;
bool translateids = false;
bool globaloption = false;
XrdOucString subcmd = subtokenizer.GetToken();
if (wants_help(arg1)) {
......@@ -73,7 +74,11 @@ com_recycle(char* arg1)
if (param == "-n") {
translateids = true;
} else {
options.push_back(param.c_str());
if (param == "-g") {
globaloption = true;
} else {
options.push_back(param.c_str());
}
}
}
} else {
......@@ -85,15 +90,15 @@ com_recycle(char* arg1)
goto com_recycle_usage;
}
if ((subcmd == "ls") && args.size()) {
if ((subcmd == "ls") && (args.size() && globaloption)) {
goto com_recycle_usage;
}
if ((subcmd == "purge") && options.size()) {
if ((subcmd == "purge") && (options.size() && !globaloption)) {
goto com_recycle_usage;
}
if ((subcmd == "purge") && args.size()) {
if ((subcmd == "purge") && (args.size() && globaloption)) {
goto com_recycle_usage;
}
......@@ -162,6 +167,10 @@ com_recycle(char* arg1)
in += "&mgm.recycle.printid=n";
}
if (globaloption) {
in += "&mgm.recycle.global=1";
}
global_retc = output_result(client_command(in));
return (0);
com_recycle_usage:
......@@ -171,13 +180,25 @@ com_recycle_usage:
fprintf(stdout, "Options:\n");
fprintf(stdout, "recycle :\n");
fprintf(stdout,
" print status of recycle bin and if executed by root the recycle bin configuration settings.\n");
fprintf(stdout, "recycle ls :\n");
" print status of recycle bin and if executed by root the recycle bin configuration settings.\n\n");
fprintf(stdout, "recycle ls [date]:\n");
fprintf(stdout,
" list files in the recycle bin\n");
fprintf(stdout, "recycle purge :\n");
fprintf(stdout,
" [date] can be <year>,<year>/<month> or <year>/<month>/<day>\n");
fprintf(stdout,
" e.g.: recycle purge 2018/08/12\n\n");
fprintf(stdout, "recycle purge [-g|<date>]:\n");
fprintf(stdout,
" purge files in the recycle bin\n");
fprintf(stdout,
" -g : empties the recycle bin of all users\n");
fprintf(stdout,
" [date] can be <year>, <year>/<month> or <year>/<month>/<day>\n");
fprintf(stdout,
" e.g.: recycle purge 2018/03/05\n");
fprintf(stdout,
" -g cannot be combined with a date restriction\n\n");
fprintf(stdout,
"recycle restore [--force-original-name|-f] [--restore-versions|-r] <recycle-key> :\n");
fprintf(stdout,
......@@ -185,7 +206,7 @@ com_recycle_usage:
fprintf(stdout,
" --force-original-name : move's deleted files/dirs back to the original location (otherwise the key entry will have a <.inode> suffix\n");
fprintf(stdout,
" --restore-versions : restore all previous versions of a file\n");
" --restore-versions : restore all previous versions of a file\n\n");
fprintf(stdout, "recycle config --add-bin <sub-tree>:\n");
fprintf(stdout,
" configures to use the recycle bin for deletions in <sub-tree>\n");
......
......@@ -188,7 +188,8 @@ kicks in using recycle purge:
success: purged 1 bulk deletions and 0 individual files from the recycle bin!
Notice that purging only removes files of the current uid/gid role.
Running as **root** does not purge the recycle bin of all users!
Running as **root** does not purge the recycle bin of all users by default.
If you want to purge the recycle bin completely add the ``-g`` option.
Implementation
----------------
......@@ -197,12 +198,25 @@ deeper insight to administrators. All the functionality is wrapped as demonstrat
The recycle bin resides in the namespace under the proc directory under ``/recycle/``.
Each deleted objects is moved into
The old structure until release 4.3.35 was
``/recycle/<gid>/<uid>/<contracted-path>.<hex-inode>`` for files and
``/recycle/<gid>/<uid>/<contracted-path>.<hex-inode>.d`` for bulk deletions.
The new structure since release 4.3.36 is
``/recycle/<uid>/<year>/<month>/<date>/<index>/<contracted-path>.<hex-inode>`` for files and
``/recycle/<uid>/<year>/<month>/<date>/<index>/<contracted-path>.<hex-inode>.d`` for bulk deletions.
The new structure adds to purge the recycle bin easily by date:
.. code-block:: bash
EOS Console [root://localhost] |/eos/dev/2rep/subnode/> recycle purge 2018/03/01
success: purged 12 bulk deletions and 0 individual files from the recycle bin!
The internal structure is however not relevant or exported to the end-user.
The contracted path flattens the full pathname replacing '/' with '#:#'.
......
This diff is collapsed.
......@@ -68,10 +68,10 @@ public:
//! Default Constructor - use it to run the Recycle thread by callign Start
//! afterwards.
//----------------------------------------------------------------------------
Recycle():
Recycle() :
mThread(0), mPath(""), mRecycleDir(""), mRecyclePath(""),
mOwnerUid(99), mOwnerGid(99), mId(0), mWakeUp(false)
{}
mOwnerUid(99), mOwnerGid(99), mId(0), mWakeUp(false) { }
//----------------------------------------------------------------------------
//! Constructor
......@@ -81,13 +81,13 @@ public:
//! @param gid group id
//! @param id of the container or file
//----------------------------------------------------------------------------
Recycle(const char* path, const char* recycledir,
eos::common::Mapping::VirtualIdentity_t* vid, uid_t ownerUid,
gid_t ownerGid, unsigned long long id):
gid_t ownerGid, unsigned long long id) :
mThread(0), mPath(path), mRecycleDir(recycledir),
mRecyclePath(""), mOwnerUid(ownerUid), mOwnerGid(ownerGid), mId(id),
mWakeUp(false)
{}
mWakeUp(false) { }
~Recycle()
{
......@@ -121,6 +121,17 @@ public:
*/
int ToGarbage(const char* epname, XrdOucErrInfo& error);
/**
* @parame epname error printing name
* @param error error object
* @param recyclepath computed by this function
* @param index if -1, a new index directory will be created, otherwise the given one will be returned
* @return SFS_OK if ok, otherwise SFS_ERR + errno + error object set
*/
int GetRecyclePrefix(const char* epname, XrdOucErrInfo& error,
std::string& recyclepath, int index = -1);
/**
* return the path from where the action can be recycled ( this is filled after ToGarbage has been called
* @return string with the path name in the recycle bin
......@@ -139,10 +150,27 @@ public:
* @param vid of the client
* @param monitoring selects monitoring key-value output format
* @param translateids selects to display uid/gid as number or string
* @param global show files of all users as root
* @param date filter recycle bin for given date <year> or <year>/<month> or <year>/<month>/<day>
*/
static void Print(XrdOucString& stdOut, XrdOucString& stdErr,
eos::common::Mapping::VirtualIdentity_t& vid, bool monitoring,
bool transalteids, bool details);
bool transalteids, bool details,
std::string date = "",
bool global = false
);
/**
* print the recycle bin contents
* @param stdOut where to print
* @param stdErr where to print
* @param vid of the client
* @param monitoring selects monitoring key-value output format
* @param translateids selects to display uid/gid as number or string
*/
static void PrintOld(XrdOucString& stdOut, XrdOucString& stdErr,
eos::common::Mapping::VirtualIdentity_t& vid, bool monitoring,
bool transalteids, bool details);
/**
* undo a deletion
......@@ -158,14 +186,26 @@ public:
XrdOucString& options);
/**
* purge all files in the recycle bin
* purge all files in the recycle bin with new uid:<uid>/<date> structure
* @param stdOut where to print
* @param stdErr where to print
* @param vid of the client
* @PARAM date can be empty, <year> or <year>/<month> or <year>/<month>/<day>
* @return 0 if done, otherwise errno
*/
static int Purge(XrdOucString& stdOut, XrdOucString& stdErr,
eos::common::Mapping::VirtualIdentity_t& vid);
eos::common::Mapping::VirtualIdentity_t& vid,
std::string date = "",
bool global = false);
/**
* purge all files in the recycle bin
* @param stdOut where to print
* @param stdErr where to print
* @return 0 if done, otherwise errno
*/
static int PurgeOld(XrdOucString& stdOut, XrdOucString& stdErr,
eos::common::Mapping::VirtualIdentity_t& vid);
/**
* configure the recycle bin
......@@ -180,7 +220,6 @@ public:
eos::common::Mapping::VirtualIdentity_t& vid, const char* arg,
XrdOucString& options);
/**
* set the wake-up flag in the recycle thread to look at modified recycle bin settings
*/
......
......@@ -38,12 +38,25 @@ ProcCommand::Recycle()
XrdOucString monitoring = pOpaque->Get("mgm.recycle.format");
XrdOucString translateids = pOpaque->Get("mgm.recycle.printid");
XrdOucString option = pOpaque->Get("mgm.option");
XrdOucString global = pOpaque->Get("mgm.recycle.global");
XrdOucString date = pOpaque->Get("mgm.recycle.arg");
if (!date.length()) {
Recycle::PrintOld(stdOut, stdErr, *pVid, (monitoring == "m"),
!(translateids == "n"), (mSubCmd == "ls"));
}
Recycle::Print(stdOut, stdErr, *pVid, (monitoring == "m"),
!(translateids == "n"), (mSubCmd == "ls"));
!(translateids == "n"), (mSubCmd == "ls"),
date.length() ? date.c_str() : "", global == "1");
}
if (mSubCmd == "purge") {
retc = Recycle::Purge(stdOut, stdErr, *pVid);
XrdOucString global = pOpaque->Get("mgm.recycle.global");
XrdOucString date = pOpaque->Get("mgm.recycle.arg");
Recycle::PurgeOld(stdOut, stdErr, *pVid);
retc = Recycle::Purge(stdOut, stdErr, *pVid, date.length() ? date.c_str() : "",
global == "1");
}
if (mSubCmd == "restore") {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment