kdb set user/tests/hello world
#> Create a new key user/tests/hello with string "world"
kdb export user/tests/hello mmapstorage > test.mmap
Un fichier appelé test.mmap
est créé, qui peut être réimporté avec kdb import
.
Un fichier vide appelé test.mmap
est créé et le message suivant est imprimé (inclut les journaux de ENABLE_LOGGER
):
src/plugins/mmapstorage/mmapstorage.c:944:libelektra_mmapstorage_LTX_elektraPluginset: could not unlink
src/plugins/mmapstorage/mmapstorage.c:1003:libelektra_mmapstorage_LTX_elektraPluginset: strerror: Permission denied
Sorry, the error (#9) occurred ;(
Description: Insufficient permissions to open configuration file for writing. You might want to retry as root.
Reason: Permission denied
Ingroup: kdb
Module:
At: /home/klemens/data/bsc/libelektra/src/plugins/mmapstorage/mmapstorage.c:1004
Mountpoint: user
Configfile: /dev/stdout
~ Fonctionne lorsque kdb export
est appelé en tant que root. ~ (EDIT: voir le commentaire ci-dessous) kdb export user/tests/hello mmapstorage test.mmap
fonctionne également, mais est une fonctionnalité complètement non documentée de kdb export
. Donc, un meilleur message d'erreur et une documentation mise à jour pourraient être tout ce dont nous avons besoin.
Merci d'avoir essayé ceci et pour ce rapport détaillé!
Donc, un meilleur message d'erreur et une documentation mise à jour pourraient être tout ce dont nous avons besoin.
Oui, je suis entièrement d'accord.
Peut-être devrions-nous même avoir un serializable
dans infos / status # 666 et échouer explicitement si le fichier est / dev / stdout? ( @mpranj Ou y a-t-il un moyen de détecter si un fichier n'est pas mmapable? Est-ce vraiment identique à une permission refusée?)
En regardant le code (et le message d'erreur), je pense que le problème actuel est que nous ne pouvons pas appeler unlink
sur stdout
sans accès root. De plus, open
échouera probablement aussi, car stdout
est déjà ouvert. Et si stdout
est mmapable ou non dépend de ce à quoi stdout
est connecté je pense.
L'utilisation de fstat(fileno(stdout), &stat)
pour vérifier s'il s'agit d'un fichier normal peut fonctionner. Peut-être que isatty(3)
fonctionne également.
Dans tous les cas, nous pourrions simplement vérifier si le fichier de sortie est /dev/stdout
(ou CON
pour _WIN32
) et créer un fichier temporaire à utiliser avec mmap et ensuite simplement le copier dans stdout
. Ce serait bien sûr plus lent mais nous conserverions la possibilité de rediriger la sortie de kdb export
.
Peut-être devrions-nous même avoir un
serializable
dans infos / status # 666 et échouer explicitement si le fichier est / dev / stdout?
Si quoi que ce soit, j'aurais un statut humanreadable
et refuserais d'exporter vers un stdout tty, si le format n'est pas lisible par l'homme.
Fonctionne lorsque
kdb export
est appelé en tant que root.
Je reprends ça ... N'ESSAYEZ PAS CELA! L'appel de kdb export <something> mmapstorage
tant qu'utilisateur root (même si stdout est redirigé) détruit /dev/stdout
. L'utilisation de /dev/stdout
(par exemple via fopen
) ne fonctionnera pas sur votre système tant que vous n'aurez pas recréé le lien symbolique par défaut avec sudo rm /dev/stdout && sudo ln -s /dev/stdout /proc/self/fd/1
.
Je pense que la meilleure solution est que kdb export
et kdb import
fonctionnent toujours sur des fichiers temporaires. Alors kdb export
sera plus similaire à ce que fait KDB. Cela résoudrait le problème de dissociation (qui est nécessaire pour les fichiers mmaped.) L'inconvénient est uniquement la perte de performances (copie de tout le contenu nécessaire), mais l'importation / exportation fonctionnera avec tous les plugins de stockage, ce qui est à mon avis beaucoup plus important.
Je pense que la meilleure solution est que
kdb export
etkdb import
fonctionnent toujours sur des fichiers temporaires.
Je pense que les plugins devraient créer eux-mêmes le fichier temporaire, si nécessaire. De cette façon, nous évitons les pénalités de performance pour les plugins qui peuvent directement sortir vers les TTY. AFAIK mmapstorage
est actuellement le seul plugin qui ne fonctionne pas avec les TTY. Nous pourrions également ajouter un test shell simple qui garantit que tous les plugins de stockage peuvent être appelés via kdb export /some/key plugin > export.file
. La logique est également plus autonome, car c'est vraiment la responsabilité des plugins de savoir comment produire la sortie attendue.
Aussi pour kdb import
les fichiers temporaires ne sont pas nécessaires car la lecture d'un fichier devrait toujours fonctionner, même pour les TTY (si vous disposez des autorisations appropriées).
Je pense que les plugins devraient créer eux-mêmes le fichier temporaire, si nécessaire.
Ensuite, les plugins (ou plus spécifiquement mmap) auraient besoin de savoir s'il est utilisé dans KDB ou kdb export
.
@mpranj Quelle est votre opinion? Cela peut-il être corrigé dans le plugin mmap?
De cette façon, nous évitons les pénalités de performance pour les plugins qui peuvent directement sortir vers les TTY.
Dans quels cas cette pénalité de performance est-elle un problème? Peut-être dans la sauvegarde / restauration pour chaque cas de test?
AFAIK mmapstorage est actuellement le seul plugin qui ne fonctionne pas avec les TTY.
Pour l'exportation oui. Mais pour l'importation, nous avions plusieurs plugins qui ne fonctionnent pas. Si un plugin utilise fseek ou similaire, il ne peut évidemment pas fonctionner, par exemple csvstorage ou mozprefs. (le vidage devrait maintenant être corrigé)
Nous pourrions également ajouter un test de shell simple qui garantit que tous les plugins de stockage peuvent être appelés via kdb export / some / key plugin> export.file.
Vous voulez dire tests / shell / check_export.sh ligne 46?
Dans quels cas cette pénalité de performance est-elle un problème?
En fait, probablement jamais. Tant que vous utilisez les 3 versions d'argument d'exportation / importation au lieu de piping. Voir la proposition ci-dessous.
Vous voulez dire tests / shell / check_export.sh ligne 46?
Oui, mais c'est cassé, car is_not_rw_storage
ne fonctionne pas. Même dump
n'est pas reconnu comme un plugin de stockage.
Je pense que pour résoudre ce problème rapidement et facilement, nous devons procéder comme suit:
is_not_rw_storage
dans include_common.sh.in
tests/shell/check_export.sh
afin que nous détections des problèmes comme celui-ci à l'avenir.kdb export
créez un fichier temporaire, uniquement si aucun troisième argument n'est donné. Utilisez ce fichier dans les appels kdbSet
et copiez ensuite son contenu dans stdout (ne devrait pas faire plus d'une ou deux lignes en C ++).kdb import
créez un fichier temporaire si stdin est utilisé. Copiez tout stdin dans le fichier temporaire et utilisez ce fichier pour appeler kdbGet
.kdb import
et kdb export
pour indiquer que le troisième argument existe. Indiquez également que si la version à deux arguments est utilisée, nous créons un fichier temporaire.PS. Cela pourrait être good first issue
Merci d'avoir signalé que is_not_rw_storage est cassé, j'ai ouvert le # 2423
Désolé , j'étais absent pendant une semaine et je n'ai donc pas pu me renseigner.
Les messages d'erreur mmap peuvent être trompeurs. mmap()
échoue avec EACCES
lors de la tentative de mappage de fichiers non réguliers. À ma connaissance, cela ne fonctionnera pas sur stdout. Cela ne fonctionne pas non plus avec les tuyaux, comme indiqué dans # 2209.
Depuis POSIX:
La fonction mmap () doit être prise en charge pour les objets mémoire suivants:
- Fichiers réguliers
- [SHM] Objets de mémoire partagée
- [TYM] Objets mémoire typés
En ce qui concerne les solutions dans mmapstorage, nous pouvons vérifier s'il s'agit d'un fichier régulier avec stat
et ensuite:
Je suis également ouvert à d'autres solutions. Les solutions ci-dessus ne changent pas beaucoup la logique de mmapstorage. Retravailler mmapstorage pour travailler directement avec des tuyaux ou des sorties standard n'a pas trop de sens pour moi.
Merci pour votre réponse!
Les messages d'erreur mmap peuvent être trompeurs.
Veuillez améliorer les messages d'erreur.
À ma connaissance, cela ne fonctionnera pas sur stdout. Cela ne fonctionne pas non plus avec les tuyaux
Veuillez ajouter ces informations aux messages d'erreur.
Les solutions ci-dessus ne changent pas beaucoup la logique de mmapstorage.
Comme votre plugin est actuellement le seul affecté, il est logique que vous fassiez la statistique et copiez tout si nécessaire. Ensuite, nous pourrions fermer ce problème sans modifications plus importantes du cadre.
Ensuite, nous pourrions fermer ce problème sans modifications plus importantes du cadre.
Nous devrions également mettre à jour les pages de manuel pour kdb import
et kdb export
. Actuellement, ils ne mentionnent pas les 3 versions d'argument qui ne reposent pas sur stdin / stdout.
Merci à vous deux d'avoir signalé le problème et de votre contribution!
Malheureusement, strerror
imprime ces messages d'erreur trompeurs. Je peux ajouter un indice dans ce cas.
Je ferai les changements demandés dans un PR cette semaine.
Nous devrions également mettre à jour les pages de manuel pour kdb import et kdb export. Actuellement, ils ne mentionnent pas les 3 versions d'argument qui ne reposent pas sur stdin / stdout.
Peut-être n'avons-nous pas besoin de l'argument pour spécifier le fichier? L'argument entrerait en conflit une fois que kdb import/export
prend en charge plusieurs plugins.
Je ferai les changements demandés dans un PR cette semaine.
Merci!
Peut-être n'avons-nous pas besoin de l'argument pour spécifier le fichier?
Ensuite, nous devons prendre en charge stdin
et stdout
(redirigés vers un fichier normal) dans tous les plugins. Sinon, ils ne pourront jamais être utilisés avec kdb import/export
. Cela rend sens pour mmapstorage
car il n'est pas portable, mais d'autres plugins portables (peut-être même lisibles par l'homme) peuvent également avoir besoin d'un fichier normal (par exemple s'ils utilisent fseek
).
L'argument entrerait en conflit une fois que
kdb import/export
prend en charge plusieurs plugins.
Nous pourrions facilement passer à l'utilisation des options -i FILE, --input=FILE
, -o FILE, --ouput=FILE
lorsque nous passerons à l'utilisation de elektraGetOpts
.
Oui, nous pouvons ajouter les options -i, -o. Mais réparer les plugins (ou le framework d'import / export) pour que stdin / stdout fonctionne également serait bien dans tous les cas.
Pour résoudre ce problème avec kdb export
il suffit d'implémenter la solution de contournement dans la fonction plugin-> kdbSet (). J'ai déjà mis en œuvre ceci, PR bientôt à venir.
Cela fonctionne maintenant: kdb import user/tests/ mmapstorage < test.mmap
,
mais ce n'est pas le cas: cat test.mmap | kdb import user/tests/ mmapstorage
, car encore une fois mmap ne peut pas le gérer.
Pour rendre la solution cohérente (donc complètement compatible avec les fichiers non réguliers), il serait également nécessaire de la résoudre pour la fonction kdbGet (). Il existe environ trois solutions pour cela:
Est-ce que tout cela est souhaitable ou l'ignorons-nous?
Je pense que nous pouvons l'ignorer pour le moment, car nous avons déjà quickdump. Documentez-le simplement comme n'étant pas adapté à la sérialisation. Nous allons maintenant retravailler le cadre d'import / export de toute façon, puis nous trouverons une solution appropriée. @mpranj Je vous ai
En fait, il vaut peut-être mieux que # 2639 ferme ce problème et @mpranj vous en créez un nouveau pour le problème cat ...
.
J'avais une très bonne solution (en utilisant realpath
et stat
) qui malheureusement ne fonctionnera pas sur les BSD. Cela n'a pas de sens d'y consacrer beaucoup plus de temps.
J'ai décidé de le jeter, ce qui ne rend pas mmapstorage complètement compatible avec les fichiers non réguliers. Cela ne fonctionnera qu'avec l'import / export kdb. La nouvelle solution vérifiera simplement si l'import / export kdb est utilisé, en vérifiant si le fichier est " /dev/stdin
" ou " /dev/stdout
". C'est fait de la même manière dans quickdump
.
J'avais une très bonne solution (utilisant realpath et stat) qui malheureusement ne fonctionnera pas sur les BSD.
C'est la solution commentée?
Cela n'a pas de sens d'y consacrer beaucoup plus de temps.
Vous avez raison, le cadre devrait gérer cela. J'ai créé le # 2640.
ne fonctionnera qu'avec l'importation / exportation kdb
Aussi avec la variante cat | kdb import
?
C'est fait de la même manière dans quickdump.
Où sont les différences?
Ce code peut-il être déplacé vers le framework d'import / export?
C'est la solution commentée?
Je l'ai laissé dans l'histoire mais j'ai supprimé les lignes plus tard. La meilleure solution à mon humble avis était jusqu'à https://github.com/ElektraInitiative/libelektra/pull/2639/commits/a523f9b38b56687d532f5101c7ef44c078e2308d. Notez que cela a bien fonctionné sous Linux mais pas BSD.
Un problème que j'ai rencontré est que stdin / stdout ne peut pas être open () ed sur les BSD. L'autre est que vous devez vraiment utiliser le realpath pour stat () le fichier et déterminer s'il s'agit d'un fichier normal. Sinon, stat n'a résolu qu'un seul niveau de liens symboliques pour moi. Cette approche a échoué sur les BSD pour moi, car realpath s'est résolu d'une manière ou d'une autre en un fichier inexistant.
Aussi avec le chat | Variante d'importation kdb?
Oui!
Où sont les différences?
La partie pertinente est la même, désolé pour la confusion. Ce que je voulais dire, c'est que nous strcmp pour / dev / stdin au lieu d'utiliser stat pour déterminer s'il s'agit d'un fichier normal. Cela signifie qu'il échouera toujours si nous utilisons / dev / fd /
Modifier :
Ce code peut-il être déplacé vers le framework d'import / export?
Oui, je pense que le code était presque complètement là, mais je n'ai pas eu le temps de résoudre correctement les problèmes BSD.
Commentaire le plus utile
Merci pour votre réponse!
Veuillez améliorer les messages d'erreur.
Veuillez ajouter ces informations aux messages d'erreur.
Comme votre plugin est actuellement le seul affecté, il est logique que vous fassiez la statistique et copiez tout si nécessaire. Ensuite, nous pourrions fermer ce problème sans modifications plus importantes du cadre.