প্রক্রিয়া তৈরি করে একই ফাইলের নামের জন্য একটি পৃথক ফাইল পড়া read


9

আমার কাছে একটি অ্যাপ্লিকেশন রয়েছে যা একটি ফাইল পড়ে। এর প্রসেসনাম এবং ফাইলটি কল করুন ~ /। কনফিগারেশন । যখন প্রসেসনামটি চালিত হয় এটি সর্বদা ~ / । কনফিগারেশন পড়ে এবং আলাদাভাবে কনফিগার করা যায় না। এছাড়াও অন্যান্য অ্যাপ্লিকেশনগুলি রয়েছে যা "~ / .configration" এর উপর নির্ভর করে আগে এবং পরে, তবে প্রক্রিয়া নাম চলাকালীন নয়।

Script /। কনফিগারেশনের বিষয়বস্তুগুলিকে প্রতিস্থাপন করে এমন স্ক্রিপ্টে মোড়ানোর প্রক্রিয়া নামটি একটি বিকল্প, তবে আমার সম্প্রতি একটি বিদ্যুৎ বিভ্রাট হয়েছিল (যখন বিষয়বস্তুগুলি অদলবদল করা হয়েছিল), যেখানে আমি উল্লিখিত ফাইলটির পূর্ববর্তী বিষয়বস্তুগুলি হারিয়েছি, সুতরাং এটি পছন্দসই নয়।

LD_DEBUG=files processnameনির্দিষ্ট ফাইলটি পড়ার চেষ্টা করার সময় বিভিন্ন বিষয়বস্তু পড়তে কোনও প্রক্রিয়া বোকা করার জন্য কি কোনও উপায় রয়েছে (সম্ভবত দূরবর্তী সম্পর্কিত কিছু ব্যবহার করা ?)? এক্সিকিউটেবলের মধ্যে ফাইলের নাম অনুসন্ধান এবং প্রতিস্থাপন করা কিছুটা আক্রমণাত্মক তবে এটির পাশাপাশি কাজ করা উচিত।

আমি জানি যে কর্নেল মডিউলটি open()কল করা যায় ( https://news.ycombinator.com/item?id=2972958 ) এটি গ্রহণ করে , তবে কি আরও সহজ বা ক্লিনার উপায় আছে?

সম্পাদনা: প্রসেসনেস ut /কনফিগারেশন এক্সিকিউটেবলের জন্য অনুসন্ধান করার সময় আমি আবিষ্কার করেছি যে এটি file / .configration পড়ার আগেই অন্য একটি ফাইল নাম পড়ার চেষ্টা করেছিল । সমস্যা সমাধান.


2
এটি কিছুটা অনুরূপ সমস্যার মতোইLD_PRELOAD বা FUSE এর মাধ্যমে করা যেতে পারে তবে আমি কোনও বিদ্যমান বাস্তবায়ন জানি না।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

উত্তর:


6

লিনাক্স সাম্প্রতিক সংস্করণে, আপনি পারেন ভাগমুক্ত নামস্থান মাউন্ট । এটি হ'ল, আপনি এমন প্রক্রিয়াগুলি শুরু করতে পারেন যা ভার্চুয়াল ফাইল সিস্টেমটি আলাদাভাবে দেখায় (ফাইল সিস্টেমগুলি পৃথকভাবে মাউন্ট করা থাকে)।

এটি দিয়েও করা যেতে পারে chrootতবে unshareএটি আপনার ক্ষেত্রে আরও খাপ খায়।

মত chroot, আপনার প্রয়োজন unshareমাউন্ট নেমস্পেসে প্রাইভেলজড সুপারভাইজার ।

সুতরাং, আপনার কাছে আছে ~/.configurationএবং ~/.configuration-for-that-cmdফাইলগুলি বলুন।

আপনি এমন একটি প্রক্রিয়া শুরু করতে পারেন যার ~/.configurationজন্য ~/.configuration-for-that-cmdএটি সেখানে একটি বাঁধার মাউন্ট এবং সেখানে কার্যকর that-cmdকরতে পারেন।

মত:

sudo unshare -m sh -c "
   mount --bind '$HOME/.configuration-for-that-cmd' \
                '$HOME/.configuration' &&
     exec that-cmd"

that-cmdএবং এর সমস্ত বংশধর প্রক্রিয়া আলাদা দেখতে পাবে ~/.configuration

that-cmdউপরের হিসাবে চলতে হবে root, sudo -u another-user that-cmdএটি অন্য ব্যবহারকারী হিসাবে চালানোর প্রয়োজন হলে ব্যবহার করুন


আমি মনে করি আপনার সমাধান সম্ভবত এখন পর্যন্ত প্রদত্ত দুটিটির চেয়ে ভাল (এবং ওপি পরে কী হবে তা দেওয়া হয়েছে, সময়ের ভিত্তিতে পুনর্নির্দেশ করা বা একটি সনাক্তকরণ প্রক্রিয়ার ফলাফলগুলি আমার কাছে যথেষ্ট মনে হয়), তবে আমি মনে করি তারা একটি একক ফাইল চাইছেন অন্যভাবে দেখাতে। সুতরাং তাদের সম্ভবত এটি অন্য কোথাও মাউন্ট করতে হবে এবং পুনর্নির্দেশের আসল বিন্দু হিসাবে কাজ করতে বিভিন্ন মাউন্ট পয়েন্টগুলি গণনা করে একটি সিমিলিংক ব্যবহার করতে হবে।
ব্র্যাচলে

1
@ জোয়েলডাভিস, আপনি যে কোনও ফাইলকে বাঁধতে পারেন কেবল ডিরেক্টরি ফাইলগুলি।
স্টাফেন চেজেলাস

তিল। যদিও সেখানে সুরক্ষা নিয়ন্ত্রণ আছে? আমি এটি একটি উপ-ডিরেক্টরি ব্যবহার করে চেষ্টা করেছি যেখানে আমি ছিলাম (/ etc / fstab থেকে আবদ্ধ) এবং এটি "ডিরেক্টরি নয়" ফিরিয়ে দিয়েছে তবে আমি একই জিনিসটি অধীনে করেছি /testএবং এটি ইস্যু ছাড়াই কাজ করেছে।
ব্র্যাচলে

প্রকৃতপক্ষে, এনএম আমি পার্থক্যটি দেখতে পাচ্ছি, আমি এটি প্রথমবার একটি ডিরেক্টরিতে এবং পরের বার একটি ফাইলের সাথে করেছিলাম। আমি ধরে নিচ্ছিলাম যে এটি যথাযথভাবে ভিএফএসকে পুনঃনির্দেশ / পরিবর্তন করবে। যাইহোক, নতুন খেলনা জন্য ধন্যবাদ।
ব্র্যাচলে

3

নরম লিঙ্কগুলি।

দুটি কনফিগারেশন ফাইল তৈরি করুন এবং বেশিরভাগ সময় নরম লিঙ্কের সাথে একটিতে নির্দেশ করুন তবে বিশেষ অ্যাপ্লিকেশন চলমান থাকাকালীন নরম লিঙ্কটি অন্যটির দিকে নির্দেশ করুন।

(আমি জানি এটি একটি ভয়ঙ্কর হ্যাক, তবে এটি ফাইলের বিষয়বস্তু পরিবর্তনের চেয়ে কিছুটা বেশি নির্ভরযোগ্য)।

বা, ip হোমকে কারসাজি করুন।

বিরক্তিকর প্রক্রিয়া শুরু হওয়া স্ক্রিপ্টে, নিয়মিত $ হোম ডিরেক্টরি অনুসারে $ HOME কে কিছু সেট করুন এবং আপনার অ্যাপ্লিকেশনটিকে সেখানে অবস্থিত কনফিগারেশন ফাইলটি ব্যবহার করা উচিত (পরীক্ষিত, এবং বেসিক শেল কমান্ডগুলির জন্য কাজ করে, $ Home এ প্রসারিত হয়)।

প্রক্রিয়া অন্যটি কী করে তার উপর নির্ভর করে $ বাড়ির পরিবর্তনের অনিচ্ছাকৃত পরিণতি হতে পারে (যেমন আউটপুট ফাইলগুলি ভুল জায়গায় শেষ হতে পারে))


1

আপনি এটি LD_PRELOAD কৌশল ব্যবহার করে করতে পারেন । এখানে এমন একটি বাস্তবায়ন রয়েছে যা কোনও নির্দিষ্ট উপসর্গের সাথে অন্য কোনও স্থানে যাত্রা শুরু করে maps কোডটি গিথুবেও রয়েছে

উদাহরণস্বরূপ, আপনি /etc/রুট না হয়ে কোনও ফাইলের অস্তিত্ব নকল করতে পারেন । এটি নিজস্ব ক্লাউড ক্লায়েন্টের জন্য প্রয়োজনীয় ছিল যা ফাইল /etc/ownCloud/sync-exclude.listউপস্থিত না থাকলে কাজ করতে অস্বীকার করে work

এটি একটি ডিরেক্টরিকে অন্য ডিরেক্টরিতে ম্যাপ করার জন্য open()এবং open64()ফাংশনগুলিকে ওভাররাইড করে কাজ করে , উদাহরণস্বরূপ সমস্ত open()কলগুলিতে /etc/ownCloud/...পুনঃনির্দেশ করা যেতে পারে /home/user1/.etc/ownCloud/...

কেবলমাত্র সামঞ্জস্য করুন path_map, তারপরে সংকলন করুন এবং আপনার প্রোগ্রামটি পূর্ববর্তী লোড দিয়ে চালিত করুন:

gcc -std=c99 -Wall -shared -fPIC path-mapping.c -o path-mapping.so -ldl

LD_PRELOAD=/path/to/my/path-mapping.so someprogram

এর উত্স কোড path-mapping.c:

#define _GNU_SOURCE

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <dlfcn.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>
#include <malloc.h>

// List of path pairs. Paths beginning with the first item will be
// translated by replacing the matching part with the second item.
static const char *path_map[][2] = {
    { "/etc/ownCloud/", "/home/user1/.etc/ownCloud/" },
};

__thread char *buffer = NULL;
__thread int buffer_size = -1;

typedef FILE* (*orig_fopen_func_type)(const char *path, const char *mode);
typedef int (*orig_open_func_type)(const char *pathname, int flags, ...);

static int starts_with(const char *str, const char *prefix) {
    return (strncmp(prefix, str, strlen(prefix)) == 0);
}

static char *get_buffer(int min_size) {
    int step = 63;
    if (min_size < 1) {
        min_size = 1;
    }
    if (min_size > buffer_size) {
        if (buffer != NULL) {
            free(buffer);
            buffer = NULL;
            buffer_size = -1;
        }
        buffer = malloc(min_size + step);
        if (buffer != NULL) {
            buffer_size = min_size + step;
        }
    }
    return buffer;
}

static const char *fix_path(const char *path)
{
    int count = (sizeof path_map) / (sizeof *path_map); // Array length
    for (int i = 0; i < count; i++) {
        const char *prefix = path_map[i][0];
        const char *replace = path_map[i][1];
        if (starts_with(path, prefix)) {
            const char *rest = path + strlen(prefix);
            char *new_path = get_buffer(strlen(path) + strlen(replace) - strlen(prefix));
            strcpy(new_path, replace);
            strcat(new_path, rest);
            printf("Mapped Path: %s  ==>  %s\n", path, new_path);
            return new_path;
        }
    }
    return path;
}


int open(const char *pathname, int flags, ...)
{
    const char *new_path = fix_path(pathname);

    orig_open_func_type orig_func;
    orig_func = (orig_open_func_type)dlsym(RTLD_NEXT, "open");

    // If O_CREAT is used to create a file, the file access mode must be given.
    if (flags & O_CREAT) {
        va_list args;
        va_start(args, flags);
        int mode = va_arg(args, int);
        va_end(args);
        return orig_func(new_path, flags, mode);
    } else {
        return orig_func(new_path, flags);
    }
}

int open64(const char *pathname, int flags, ...)
{
    const char *new_path = fix_path(pathname);

    orig_open_func_type orig_func;
    orig_func = (orig_open_func_type)dlsym(RTLD_NEXT, "open64");

    // If O_CREAT is used to create a file, the file access mode must be given.
    if (flags & O_CREAT) {
        va_list args;
        va_start(args, flags);
        int mode = va_arg(args, int);
        va_end(args);
        return orig_func(new_path, flags, mode);
    } else {
        return orig_func(new_path, flags);
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.